import hashlib
import chardet
import json
import redis
import time
from gmssl import sm2
from lib.client import HttpClient
from lib.config import localProxy,_redis
from tornado.httputil import url_concat
from log import app_log

logger = app_log(__name__)
def md5(_str):
    # 创建md5对象
    hl = hashlib.md5()
    # Tips
    # 此处必须声明encode
    # 若写法为hl.update(str)  报错为： Unicode-objects must be encoded before hashing
    hl.update(_str.encode(encoding='utf-8'))
    return hl.hexdigest()


class Proxy(object):
    def __init__(self):
        self._isErr = False
        self._errMsg = ""
        self._host = ""
        self._port = 000
        self._timeOut = 3

    @property
    def host(self):
        return

    @host.setter
    def host(self, value):
        self._host = value

    @property
    def port(self):
        return

    @port.setter
    def port(self, value):
        if not isinstance(value, int):
            return TypeError(f"端口必须是一个int:{value}")
        self._port = value

    @property
    def isErr(self):
        return self._isErr

    @property
    def errMsg(self):
        return self._errMsg

    def __err(self, errMsg):
        self._isErr = True
        self._errMsg = str(errMsg)

class ProxyDataPlatform(Proxy):
    def __init__(self):
        super(ProxyDataPlatform, self).__init__()
        self._headers = {"Content-Type":"application/json","Dev-Type":"Terminal"}
        self._devType = "Terminal"
        self._host = localProxy.host
        self._port = localProxy.port
        self._protocol = localProxy.protovol

    @property
    def sm4Key(self):
        return self._sm4Key

    @sm4Key.setter
    def sm4Key(self, value):
        self._sm4Key = value

    @property
    def protocol(self):
        return

    @protocol.setter
    def protocol(self, value):
        if value not in ["http", "https"]:
            raise ValueError(f"代理协议类型不合法:{value}")
        self._protocol = value

    @property
    def appKey(self):
        return

    @appKey.setter
    def appKey(self, value):
        self._appKey = value

    @property
    def devType(self):
        return

    @devType.setter
    def devType(self, value):
        self._devType = value

    def __signatuer(*args, **kwargs):
        # 签名认证
        keys = sorted(kwargs.keys())
        key_str = "".join(keys)
        values_str = ""
        for key in keys:
            values_str += str(kwargs[key])
        s = "{}{}".format(key_str, values_str.replace('\'', '').replace(' ', '').replace('\"', ''))
        # 加密
        signature_str1 = md5(s)
        # 加盐加密na
        signature_str = md5("NCSS-SASH-{}".format(signature_str1))
        return signature_str

    def _json(self, r):
        if r.code != 200:
            self._err(f"网络状态异常:{r.code}")
        try:
            e = chardet.detect(r.body)
            data = json.loads(str(r.body, encoding=e['encoding']))
        except Exception as e:
            self._err(f"请求数据转换异常;{str(e)}")
            return
        assert data["err_code"] == 0, f"{data['err_code']};MSG:{data['err_msg']}"
        return data["data"]

    def _err(self, errMsg):
        self._isErr = True
        self._errMsg = str(errMsg)

    async def post(self, url, body, headers=None, timeOut=1):
        sign = self.__signatuer(**body)
        self._headers["Authorization"] = f"Bearer {sign}"
        client = HttpClient()
        client.set_header(self._headers)
        url = url_concat(f"{self._protocol}://{self._host}:{self._port}{url}", dict(_time=str(int(time.time()))))
        try:
            r = await client.post(url, body, headers, timeOut)
            return self._json(r)
        except Exception as e:
            self._err(e)

class ProxyUniversalPlatform(ProxyDataPlatform):
    def __init__(self):
        super(ProxyUniversalPlatform,self).__init__()

    
    def _json(self, r,isWholeResult=False):
        if r.code != 200:
            self._err(f"网络状态异常:{r.code}")
        try:
            e = chardet.detect(r.body)
            data = json.loads(str(r.body, encoding=e['encoding']))
        except Exception as e:
            self._err(f"请求数据转换异常;{str(e)}")
            return
        if isWholeResult:
            return data
        assert data["err_code"] == 0, f"{data['err_code']};MSG:{data['err_msg']}"
        return data["data"]
    
    async def post(self, url, body, headers=None, timeOut=1,isWholeResult=False):
        client = HttpClient()
        client.set_header(self._headers)
        try:
            r = await client.post(url,body,headers,timeOut)
            return self._json(r,isWholeResult)
        except Exception as e:
            self._err(e)


redisClient = redis.Redis(host=_redis.host,
                          port=_redis.port,
                          password=_redis.password,
                          decode_responses=True)


'''class XgsProxy(Proxy):
    def __init__(self,publicKey="",privateKey=""):
        super(XgsProxy,self).__init__()
        self._host = "stnas.mamato.com"
        self._port = 8086
        self._protocol = "https"
        self.publicKey = publicKey
        self.privateKey = privateKey
        self._isErr = False
        self._errMsg = ""

    def _err(self, errMsg):
        self._isErr = True
        self._errMsg = str(errMsg)

    def _json(self, r):
        try:
            data = json.loads(str(r))
        except Exception as e:
            self._err(f"请求数据转换异常;{str(e)}")
            return
        
        return data

    def post(self,url, data, headers=None, timeOut=1):
        try:
            sign_data = bytes(str(data).replace("'", "\"").replace(" ", ""),encoding='utf8') # bytes类型
            sm2_crypt = sm2.CryptSM2(public_key=self.publicKey, private_key=self.privateKey,mode=1,asn1=True)
            sign = sm2_crypt.sign_with_sm3(sign_data) #  16进制
        except Exception as e:
            self._err(f"加密过程中异常:{e}")
            return
        body = {
        "msgData": data,
        "digitalSign": sign
        }
        logger.info(f"send=======>{body}")
        String = jpype.JClass('java.lang.String')
        Integer = jpype.JClass('java.lang.Integer')
        try:
            res = "{}"
            java = jarhttpClient.stream()
            res = java.doHttps(String(self._host),Integer(self._port),String(url),String(json.dumps(body)))
            logger.info(f"res============>{res}")
        except Exception as e:
            self._err(f"请求器内部异常:{e}")
        try:
            return self._json(res)
        except Exception as e:
            self._err(e)

        # try:
        #     pass
        # except Exception as e:
        #     self._err(f"解密过程中异常:{e}")'''