from gm_types.ascle import ERROR
from helios.rpc.exceptions import RPCFaultException

from utils.base import APIView
from utils.channel_package_tools import ChannelPackage
from utils.logger import error_logger
from utils.channel_task import version_release_task


class Vendor(APIView):
    def get(self, request):
        """
        获取渠道商列表
        :param request:
        :return:
        """
        query = request.GET.get('q', '')
        page = int(request.GET.get('page', 1))
        offset = int(request.GET.get('offset', 30))

        data = request.rpc.origin['endpoint'](
            query=query, start=(page - 1) * offset, offset=offset
        ).unwrap()
        return data


class ChannelList(APIView):
    def get(self, request):
        """
        渠道列表
        :param request:
        :return:
        """
        page = int(request.GET.get('page', 1))
        offset = int(request.GET.get('limit', 10))
        filters = self.handle_filter(request.GET.get('filter', ""))
        try:
            channel_list = self.rpc['endpoint'](
                start=(page - 1) * offset, offset=offset, filters=filters
            ).unwrap()
        except Exception as e:
            error_logger.error(u'获取渠道列表失败：%s', e)
            raise e
        data = [
            {
                'name': data.get('name'),
                'url_name': data.get('url_name'),
                'pack': data.get('pack'),
                'download_url': data.get(),  # TODO 拼接下载链接 最近的一次发布
            }
            for data in channel_list]

        return self.write_success(message='获取渠道列表成功', data=data)


class Channel(APIView):
    def get(self, request):
        """
        渠道详情
        :param request:
        :return:
        """
        channel_id = request.GET.get('channel_id', 0)
        if not channel_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        try:
            channel_data = self.rpc['endpoint'](channel_id=channel_id).unwrap()
        except Exception as e:
            error_logger.error(u'获取渠道详情失败：%s', e)
            raise e
        channel = {
            'channel_id': channel_data.get('channel_id', 0),
            'channel_name': channel_data.get('name'),
            'url_name': channel_data.get('url_name'),
            'auto_pack': channel_data.get('pack'),
            'channel_vendor': channel_data.get('vendor'),
            'channel_type': channel_data.get('type'),
        }
        return self.write_success(message='获取渠道详情成功', data=channel)

    def post(self, request):
        """
        渠道创建 / 编辑
        :param request:
        :return:
        """
        channel_id = request.POST.get('channel_id', '')
        channel_name = request.POST.get('name', '')
        url_name = request.POST.get('url_name', '')
        auto_pack = request.POST.get('pack', True)
        channel_vendor = request.POST.get('vendor', 0)
        channel_type = request.POST.get('type', 2)
        if not all([channel_name, url_name, channel_vendor]):
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        if channel_id:   # 编辑渠道信息
            try:
                self.rpc['endpoint'](
                    channel_id=channel_id, name=channel_name, pack=auto_pack,
                    vendor=channel_vendor, type=channel_type
                ).unwrap()
            except RPCFaultException as e:
                raise e
            return self.write_success(message='操作成功', data={})
        else:  # 创建渠道信息
            try:
                self.rpc['endpoint'](
                    name=channel_name, pack=auto_pack, vendor=channel_vendor, type=channel_type
                ).unwrap()
            except RPCFaultException as e:
                raise e
            return self.write_success(message='操作成功', data={})


class ChannelPacked(APIView):
    def get(self, request):
        """
        当前渠道已经打包的所有版本
        :param request:
        :return:
        """
        channel_id = request.GET.get('channel_id')
        if not channel_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        try:
            channel_data = self.rpc['endpoint'](channel_id=channel_id).unwrap()
        except Exception as e:
            error_logger.error(u'获取渠道打包列表失败：%s', e)
            raise e
        channel = [
            {
                'version': data.get('version', 0),
                'channel_name': data.get('name'),
                'packed_time': data.get('packed_time'),
                'release_time': data.get('release_time'),
                'is_released': data.get('is_released'),
                'download_url': '',  # TODO 拼接下载链接
            }
            for data in channel_data]
        return self.write_success(message='获取渠道打包列表成功', data=channel)

    def post(self, request):
        """
        当前版本的渠道包发布
        :param request:
        :return:
        """
        version2channel_id = request.POST.get('id')
        if not version2channel_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')

        # get version-channel object
        version2channel = self.rpc['endpoint'](id=version2channel_id).unwrap()
        version = version2channel['version']
        channel = version2channel['channel']
        ChannelPackage.publish_apk(channel, version)
        try:
            self.rpc['endpoint'](id=version2channel_id).unwrap()  #发布完成 修改状态
        except RPCFaultException as e:
            error_logger.error(u'发布失败：%s', e)
            return self.write_fail(code=-1, message='发布失败！')
        return self.write_success(data={}, message='发布成功！')


class VersionPackedChannel(APIView):
    def get(self, request):
        """
        当前版本所有已打包渠道列表
        :param request:
        :return:
        """
        version_id = request.GET.get('version__id', '')
        page = int(request.GET.get('page', 1))
        offset = int(request.GET.get('offset', 10))
        if version_id:
            version = self.rpc['endpoint'](version_id=version_id).unwrap()
            # 母包地址 由七牛上传返回
            base_apk_url = ChannelPackage.apk_url(channel='', version=version['version'])
        else:
            base_apk_url = ''
            version = {}
        version2channels = self.rpc['endpoint'](
            version_id=version, start=(page - 1) * offset, offset=offset).unwrap()
        data = {
            'version': [{
                'version': item.get('version'),
                'name': item.get('name'),
                'packed_time': item.get('packed_time'),
                'download_url': '',
                'release_time': item.get('release_time'),
                'is_released': item.get('is_released'),
                } for item in version2channels],
            'base_apk_url': base_apk_url,
        }
        return self.write_success(data=data)


class VersionList(APIView):
    def get(self, request):
        """
        所有版本列表
        :param request:
        :return:
        """
        page = int(request.GET.get('page', 1))
        offset = int(request.GET.get('offset', 10))
        filters = self.handle_filter(request.GET.get('filter', ""))
        try:
            version_list = self.rpc['endpoint'](
                start=(page - 1) * offset, offset=offset, filters=filters
            ).unwrap()
        except Exception as e:
            error_logger.error(u'获取版本列表失败：%s', e)
            raise e
        data = [
            {
                'version': item.get('version'),
                'MD5': item.get('MD5'),
                'release_time': item.get('release_time'),
            } for item in version_list
        ]
        return self.write_success(data=data)


class VersionDetailUpdate(APIView):
    def get(self, request):
        """
        版本详情
        :param request:
        :return:
        """
        version_id = request.GET.get('version_id')
        if not version_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        version_info = self.rpc['endpoint'](version_id=version_id).unwrap()
        data = {
            'version': version_info['version'],
            'release_time': version_info['release_time'],
            'md5': version_info['md5'],
            'description': version_info['description'],
        }
        return self.write_success(data=data, message='操作成功')

    def post(self, request):
        """
        版本信息编辑 只允许修改描述
        :param request:
        :return:
        """
        version_id = request.POST.get('version_id')
        desc = request.POST.get('desc')
        if not version_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        try:
            self.rpc['endpoint'](version_id=version_id, description=desc)
        except RPCFaultException as e:
            error_logger.error(e)
            return self.write_fail(code=-1, message='操作失败')
        return self.write_success(data={}, message='操作成功')


class BatchPublishVersion(APIView):
    def post(self, request):
        """
        批量发布 并邮件通知
        :param request:
        :return:
        """
        version_id = request.POST.get('version_id')
        if not version_id:
            error_logger.error(u'参数不完整')
            return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整')
        try:
            packed_channels = self.rpc['endpoint'](version_id=version_id).unwrap()
        except RPCFaultException as e:
            error_logger.error(u'获取渠道失败%s', e)
            return self.write_fail(code=-1, message='获取渠道失败！')
        version_release_task.delay(packed_channels)
        return self.write_success(data={}, message='操作成功')
