"""Estado local del xamiSDK.

Guarda en el directorio de configuracion (~/.xamisdk por defecto):
- keys/sdk_private.pem   : la privada RSA del SDK (chmod 600, NUNCA sale)
- keys/sdk_public.pem    : la publica del SDK
- keys/xami_public.pem   : la publica de Xami (recibida en el pareo)
- state.json             : matricula, token, receive_url, endpoint, tenant, etc.

Ver docs/servicios_xamiSDK.md.
"""
from __future__ import annotations
import json
import os
import stat

DEFAULT_DIR = os.environ.get("XAMISDK_HOME", os.path.expanduser("~/.xamisdk"))


class Config:
    def __init__(self, base_dir: str = DEFAULT_DIR):
        self.base_dir = base_dir
        self.keys_dir = os.path.join(base_dir, "keys")
        self.state_path = os.path.join(base_dir, "state.json")

    # ---- directorios ----
    def ensure_dirs(self):
        os.makedirs(self.keys_dir, exist_ok=True)
        os.chmod(self.base_dir, stat.S_IRWXU)     # 700
        os.chmod(self.keys_dir, stat.S_IRWXU)     # 700

    # ---- llaves ----
    def _key_path(self, name: str) -> str:
        return os.path.join(self.keys_dir, name)

    def save_sdk_keypair(self, private_pem: str, public_pem: str):
        priv = self._key_path("sdk_private.pem")
        with open(priv, "w") as f:
            f.write(private_pem)
        os.chmod(priv, stat.S_IRUSR | stat.S_IWUSR)   # 600
        with open(self._key_path("sdk_public.pem"), "w") as f:
            f.write(public_pem)

    def save_xami_public(self, public_pem: str):
        with open(self._key_path("xami_public.pem"), "w") as f:
            f.write(public_pem)

    def sdk_private_pem(self) -> str:
        with open(self._key_path("sdk_private.pem")) as f:
            return f.read()

    def sdk_public_pem(self) -> str:
        with open(self._key_path("sdk_public.pem")) as f:
            return f.read()

    def xami_public_pem(self) -> str:
        with open(self._key_path("xami_public.pem")) as f:
            return f.read()

    def has_keys(self) -> bool:
        return os.path.exists(self._key_path("sdk_private.pem"))

    # ---- estado (state.json) ----
    def load_state(self) -> dict:
        if not os.path.exists(self.state_path):
            return {}
        try:
            with open(self.state_path) as f:
                return json.load(f)
        except Exception:
            return {}

    def save_state(self, state: dict):
        with open(self.state_path, "w") as f:
            json.dump(state, f, indent=2)
        os.chmod(self.state_path, stat.S_IRUSR | stat.S_IWUSR)   # 600

    def update_state(self, **kwargs):
        st = self.load_state()
        st.update(kwargs)
        self.save_state(st)
        return st

    def is_paired(self) -> bool:
        return bool(self.load_state().get("paired"))
