"""Shared helpers for interacting with HashiCorp Vault."""

from __future__ import annotations

import time
from typing import Any, Optional, TYPE_CHECKING

import hvac
import requests

if TYPE_CHECKING:
    from hieromem_api.settings import APISettings


class VaultClientFactory:
    """Lazily creates authenticated Vault clients with simple caching."""

    def __init__(self, settings: APISettings) -> None:
        self._settings = settings
        self._client: Optional[hvac.Client] = None
        self._last_auth: float = 0.0
        self._config = (
            settings.vault_addr,
            settings.vault_token,
            settings.vault_namespace,
        )

    def client(self) -> Optional[hvac.Client]:
        if not self._settings.use_vault:
            return None

        addr = self._settings.vault_addr
        token = self._settings.vault_token
        namespace = self._settings.vault_namespace
        if not addr or not token:
            return None

        # Reuse the client if we authenticated recently.
        now = time.time()
        if self._client and now - self._last_auth < self._settings.vault_client_ttl:
            return self._client

        client = hvac.Client(url=addr, token=token, namespace=namespace)
        if not client.is_authenticated():
            return None

        self._client = client
        self._last_auth = now
        return self._client


_CLIENT_FACTORY: VaultClientFactory | None = None


def _get_factory(settings: APISettings) -> VaultClientFactory:
    global _CLIENT_FACTORY
    config = (settings.vault_addr, settings.vault_token, settings.vault_namespace)
    if _CLIENT_FACTORY is None or getattr(_CLIENT_FACTORY, "_config", None) != config:
        _CLIENT_FACTORY = VaultClientFactory(settings)
    return _CLIENT_FACTORY


def read_kv_secret(settings: APISettings, path: str) -> dict[str, Any]:
    """Read a KV v2 secret, returning an empty dict on failure."""

    factory = _get_factory(settings)
    client = factory.client()
    if client is None:
        return {}
    try:
        secret = client.secrets.kv.v2.read_secret_version(path=path)
        return secret.get("data", {}).get("data", {})
    except Exception:
        return {}


def write_kv_secret(settings: APISettings, path: str, data: dict[str, Any]) -> bool:
    """Write a KV v2 secret payload, returning success status."""

    factory = _get_factory(settings)
    client = factory.client()
    if client is None:
        return False
    try:
        client.secrets.kv.v2.create_or_update_secret(path=path, secret=data)
        return True
    except Exception:
        return False


def fetch_jwks(url: str) -> dict[str, Any]:
    """Fetch JWKS payload from an HTTPS endpoint."""

    response = requests.get(url, timeout=5)
    response.raise_for_status()
    return response.json()


__all__ = ["VaultClientFactory", "read_kv_secret", "write_kv_secret", "fetch_jwks"]
