from opn_api.api.client import OPNsenseClientConfig
from pyfsense_client.v1.client import ClientConfig as ClientConfigV1
from pyfsense_client.v2.client import ClientConfig as ClientConfigV2

from .encrypt import EncryptedRedis


class ConfigLoader:
    def __init__(self, name: str):
        self.name = name
        self._redis = EncryptedRedis()

    def get_router_type(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:type")

    def _get_client_token(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:client_token")

    def _get_client_id(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:client_id")

    def _get_hostname(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:hostname")

    def _get_api_key(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:api_key")

    def _get_api_secret(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:api_secret")

    def _get_base_url(self) -> str:
        return self._redis.get_decrypted(f"routers:{self.name}:base_url")

    def _get_verify_ssl(self) -> bool:
        verify_ssl = self._redis.get_decrypted(f"routers:{self.name}:verify_ssl")
        if verify_ssl and verify_ssl.lower() == "true":
            return True
        return False

    def get_client_config(self):
        router_type = self.get_router_type()
        if router_type == "pfsenseV1":
            config_data = {
                "hostname": self._get_hostname(),
                "mode": "api_token",
                "client_id": self._get_client_id(),
                "client_token": self._get_client_token(),
                "verify_ssl": self._get_verify_ssl(),
            }
            return ClientConfigV1(**config_data)
        elif router_type == "pfsenseV2":
            config_data = {
                "host": self._get_hostname(),
                "verify_ssl": self._get_verify_ssl(),
                "api_key": self._get_api_key(),
            }
            return ClientConfigV2(**config_data)
        elif router_type == "opnsense":
            config_data = {
                "api_key": self._get_api_key(),
                "api_secret": self._get_api_secret(),
                "base_url": self._get_base_url(),
                "ssl_verify_cert": self._get_verify_ssl(),
                "ca": None,
                "timeout": 10,
            }
            return OPNsenseClientConfig(**config_data)
        else:
            raise ValueError(f"Unknown router type: {router_type}")

    def list_clients(self):
        # Create a list of all clients based upon redis key names
        keys = self._redis.list_keys(namespace_pattern="routers:*")
        clients = set()
        for key in keys:
            routers, client, key_name = key.decode("utf-8").split(":")
            clients.add(client)
        return clients


class CredentialStore:
    def __init__(self, name: str):
        self.name = name
        self._redis = EncryptedRedis()

    def _store_router_type(self, router_type: str):
        self._redis.set_encrypted(f"routers:{self.name}:type", router_type)

    def _store_client_token(self, token: str):
        self._redis.set_encrypted(f"routers:{self.name}:client_token", token)

    def _store_client_id(self, client_id: str):
        self._redis.set_encrypted(f"routers:{self.name}:client_id", client_id)

    def _store_hostname(self, hostname: str):
        self._redis.set_encrypted(f"routers:{self.name}:hostname", hostname)

    def _store_api_key(self, api_key: str):
        self._redis.set_encrypted(f"routers:{self.name}:api_key", api_key)

    def _store_api_secret(self, api_secret: str):
        self._redis.set_encrypted(f"routers:{self.name}:api_secret", api_secret)

    def _store_base_url(self, base_url: str):
        self._redis.set_encrypted(f"routers:{self.name}:base_url", base_url)

    def _store_verify_ssl(self, verify_ssl: str):
        self._redis.set_encrypted(f"routers:{self.name}:verify_ssl", verify_ssl)

    def set_client_config(self, config_data: dict):
        self._store_router_type(config_data["type"])
        if config_data["type"] == "pfsenseV1":
            self._store_hostname(config_data["hostname"])
            self._store_client_id(config_data["client_id"])
            self._store_client_token(config_data["client_token"])
            self._store_verify_ssl(config_data["verify_ssl"])
        elif config_data["type"] == "pfsenseV2":
            self._store_hostname(config_data["hostname"])
            self._store_api_key(config_data["api_key"])
            self._store_verify_ssl(config_data["verify_ssl"])
        elif config_data["type"] == "opnsense":
            self._store_api_key(config_data["api_key"])
            self._store_api_secret(config_data["api_secret"])
            self._store_base_url(config_data["base_url"])
            self._store_verify_ssl(config_data["verify_ssl"])
        else:
            raise ValueError(f"Unknown router type: {config_data['type']}")
