"""
Keyring utilities bound to the respected classes for serialization. The keyring objects need to be passed
around between the gateway and the server processes, while some need to be stored (encrypted) on the local
machine.
"""
from __future__ import annotations

from clarabot_crypto.keyring.account_peer import PeerAccountKeyring
from clarabot_crypto.keyring.account_self import SelfAccountKeyring
from clarabot_crypto.keyring.room import RoomKeyring


class NanoPeerAccountKeyring(PeerAccountKeyring):
    __slots__ = ()

    @classmethod
    def load_internal(cls, data: dict) -> NanoPeerAccountKeyring:
        return cls(data["id"], data["public_keys"], data["trusted"])

    def dump_internal(self) -> dict:
        """
        NOTE: These values must always be encrypted for security during transfer or in storage!
        NOTE: TOFU fingerprints are not serialized here. If they are relevant, the "trust" will be kept that they made.
        """
        return {"id": self.id.decode(), "public_keys": dict(self._public_keys), "trusted": self.trusted}


class NanoSelfAccountKeyring(SelfAccountKeyring):
    __slots__ = ()

    @classmethod
    def load_internal(cls, data: dict) -> NanoSelfAccountKeyring:
        return cls(data["id"], data["public_keys"], data["secret_keys"])

    def dump_internal(self, skip_secret_keys: bool = False) -> dict:
        """
        NOTE: These values must always be encrypted for security during transfer or in storage!
        NOTE: The trust is not serialized, because it is always set internally for current impl.
        """
        return {
            "id": self.id.decode(),
            "public_keys": dict(self._public_keys),
            "secret_keys": {} if skip_secret_keys else dict(self._secret_keys),
        }


class NanoRoomKeyring(RoomKeyring):
    __slots__ = ()

    @classmethod
    def load_internal(cls, data: dict) -> NanoRoomKeyring:
        return cls(data["id"], data["keys"])

    def dump_internal(self) -> dict:
        """
        NOTE: These values must always be encrypted for security during transfer or in storage!
        """
        return {"id": self.id.decode(), "keys": dict(self._keys)}
