import hashlib
import hmac
import pickle


class UnSecureDataError(Exception):
    pass


class PickleSerializerMixin:
    def __init__(self, *args, hash_key=None, **kwargs):
        super().__init__(*args, **kwargs)
        self._hash_key = hash_key

    async def get(self, key):
        value = await super().get(key)
        if not value:
            return value
        try:
            sign, value = value.split(b"_", 1)
        except ValueError:
            raise UnSecureDataError()
        expected_sign = self.get_sign(key, value)
        if expected_sign != sign:
            raise UnSecureDataError()
        try:
            value = pickle.loads(value, fix_imports=False, encoding="bytes")
            repr(value)
            return value
        except (pickle.PickleError, AttributeError):
            return None

    def get_sign(self, key: str, value: bytes) -> bytes:
        value = key.encode() + value
        return hmac.new(self._hash_key, value, hashlib.sha1).hexdigest().encode()

    async def set(self, key: str, value, *args, **kwargs):
        value = pickle.dumps(value, protocol=pickle.HIGHEST_PROTOCOL, fix_imports=False)
        sign = self.get_sign(key, value)
        return await super().set(key, sign + b"_" + value, *args, **kwargs)
