# -*- encoding: utf-8 -*-
"""
@File    : DeviceVersionInfoController.py
@Time    : 2024/11/20 14:20
@Author  : stephen
@Email   : zhangdongming@asj6.wecom.work
@Software: PyCharm
"""
import json

from django.http import QueryDict
from django.views import View
from Ansjer.config import LOGGER

from Model.models import DeviceVersionInfo, Device_Info
from Object.Enums.RedisKeyConstant import RedisKeyConstant
from Object.RedisObject import RedisObject
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService


class DeviceVersionInfoView(View):
    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.GET, request, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.POST, request, operation)

    def delete(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        delete = QueryDict(request.body)
        if not delete:
            delete = request.GET
        return self.validation(delete, request, operation)

    def put(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        put = QueryDict(request.body)
        return self.validation(put, request, operation)

    def validation(self, request_dict, request, operation):
        response = ResponseObject('cn')
        tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
        if tko.code != 0:
            return response.json(tko.code)
        response.lang = tko.lang
        userID = tko.userID
        if operation == 'getInfo':
            return self.get_device_version_info(userID, request, request_dict, response)
        elif operation == 'validateUserDevice':
            return self.validateUserDevice(userID, request, request_dict, response)
        else:
            return response.json(414)

    @classmethod
    def get_device_version_info(cls, user_id, request, request_dict, response):
        # 从请求字典中获取uid和version
        uid = request_dict.get('uid')
        version = request_dict.get('version')

        # 检查version是否存在
        if not version:
            return response.json(444)  # 错误代码：没有提供version

        try:
            # 示例输入字符串
            ip = CommonService.get_ip_address(request)
            LOGGER.info(f'获取设备版本配置信息 user: {user_id}, uid: {uid}, version: {version}, ip: {ip} ')

            # 从右侧分割字符串，获取版本和设备代码
            ver, d_code = version.rsplit('.', 1)  # 使用从右到左分割
            ver = ver.replace('V', '')  # 移除版本前的'V'

            # 创建Redis对象
            redis = RedisObject()
            # 构建Redis键
            version_key = RedisKeyConstant.ZOSI_DEVICE_VERSION_INFO.value + ver + d_code

            # 尝试从Redis中获取数据
            version_info = redis.get_data(version_key)
            if version_info:
                # 如果在Redis中找到了数据，直接返回
                return response.json(0, json.loads(version_info))

            # 从数据库查询设备版本信息
            device_version_qs = DeviceVersionInfo.objects.filter(d_code=d_code, software_ver=ver).values()
            if not device_version_qs.exists():
                LOGGER.info(f'获取设备版本配置信息失败 user: {user_id}, uid: {uid}, version: {version}, ip: {ip} ')
                return response.json(173)  # 错误代码：未找到设备版本信息

            # 从QuerySet中获取设备信息
            device_info = device_version_qs

            # 将设备信息序列化为JSON
            device_json = json.dumps(device_info[0])

            # 将数据写入Redis，以便后续使用
            redis.set_data(version_key, device_json, 60 * 60 * 24)  # 设置TTL为24小时
            # 返回设备信息
            return response.json(0, device_info[0])

        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @classmethod
    def validateUserDevice(cls, user_id, request, request_dict, response):
        """
        验证用户设备
        @param user_id: 用户id
        @param request: 请求
        @param request_dict: 请求参数
        @param response: 响应参数
        @return: 成功 0 失败 173
        """
        uid = request_dict.get('uid')
        serial_number = request_dict.get('serialNumber')
        app_bundle_id = request_dict.get('appBundleId')
        m_code = request_dict.get('mCode')

        if not uid:
            return response.json(444)  # 错误代码：没有提供uid

        try:
            LOGGER.info(f'直播验证用户uid:{uid},user:{user_id},m_code:{m_code}')

            redis = RedisObject(3)
            # 构建Redis键
            device_key = f"{RedisKeyConstant.BASIC_USER.value}{user_id}:UID:{uid}"

            # 尝试从Redis中获取数据
            device_info = redis.get_data(device_key)

            # 检查缓存命中和UID匹配
            if device_info == uid:
                return response.json(0, uid)  # 缓存命中返回 0

            ip = CommonService.get_ip_address(request)
            LOGGER.info(f'直播验证用户uid:{uid},ip:{ip},serial:{serial_number},app{app_bundle_id}')

            # 从数据库查询设备版本信息
            try:
                device_qs = Device_Info.objects.filter(userID_id=user_id, UID=uid).values('UID')
                if not device_qs.exists() or uid != device_qs.first().get('UID'):
                    LOGGER.error(f'验证用户uid错误,未找到设备信息 uid:{uid}')
                    return response.json(173)  # 错误代码：未找到设备信息

                # 将数据写入Redis，以便后续使用，设置TTL为48小时
                redis.set_data(device_key, uid, 60 * 60 * 24 * 2)

                return response.json(0, uid)  # 返回设备信息

            except Exception as db_exception:
                LOGGER.error(f'数据库查询失败 user:{user_id}, uid:{uid}, error: {repr(db_exception)}')
                return response.json(500, '数据库查询错误')

        except Exception as e:
            error_line = e.__traceback__.tb_lineno
            LOGGER.error(f'验证用户uid异常 user:{user_id}, uid:{uid}, error_line:{error_line}, error_msg:{repr(e)}')
            return response.json(500, f'error_line:{error_line}, error_msg:{repr(e)}')
