import hashlib

class Sign(object):
    def __init__(self) -> None:
        super().__init__()
        self._param = ""

    @property
    def param(self):
        return self._param

    @param.setter
    def param(self, value):
        self._param = value

    def _md5(self, _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()

    def sign(self):
        '''签名计算'''
        keys = sorted(self._param.keys())
        key_str = "".join(keys)
        values_str = ""
        for key in keys:
            values_str += str(self._param[key])
        s = "{}{}".format(
            key_str,
            values_str.replace('\'', '').replace(' ', '').replace('\"', ''))
        # 加密
        signature_str1 = self._md5(s)
        # 加盐加密
        signature_str = self._md5("NCSS-SASH-{}".format(signature_str1))
        return signature_str


class AuthenticationController(object):
    def __init__(self) -> None:
        super().__init__()
        self._devType = ""  #设备类型
        self._reqSign = ""  #客户端签名
        self._isPass = False  #鉴权是否通过
        self._errMsg = "ok"  #鉴权错误信息
        self._sign = None  # 签名对象
        self._token = ""  # token --仅对PC对象
        self._session = {}

    @property
    def token(self):
        return self._token

    @token.setter
    def token(self, value):
        self._token = value

    @property
    def isPass(self):
        return self._isPass

    @isPass.setter
    def isPass(self, value):
        self._isPass = value

    @property
    def devType(self):
        return self._devType

    @devType.setter
    def devType(self, value):
        if not value:
            raise RuntimeError("因无法获取devType鉴权失败")
        self._devType = value

    @property
    def sign(self):
        return self._sign

    @sign.setter
    def sign(self, value):
        self._sign = value

    @property
    def reqSign(self):
        return self._reqSign

    @reqSign.setter
    def reqSign(self,value):
        self._reqSign = value.split(' ')[1]

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

    @errMsg.setter
    def errMsg(self,value):
        self._errMsg = value

    @property
    def session(self):
        return self._session
    
    @session.setter
    def session(self,vaule):
        self._session = vaule

    def auth(self):
        '''鉴权机制规则'''
        if self._devType not in ["HandTerminal", "Terminal", "GasTerminal","PC"]:
            self._errMsg = "设备类型不合法"
            return
        localSign = self.sign.sign() #客户端签名与本地机算出的签名比对,如果不一致有三方篡改参数嫌疑不予通过
        if self.reqSign != localSign:
            self._errMsg = f"签名比对失败:reqSign:{self.reqSign};localSign:{localSign}"
            return
        if self._devType == "PC":
            if not self._token.value:
                self._errMsg = "PC客户端无法获取token"
                return
            user = self.session.get(self._token.value)
            if not user:
                self._errMsg = "携带不合法的token"
                return
        self._isPass = True
