"""Vault temporário — API Token Cloudflare BYO (Spec 037). Nunca logar o token."""

from __future__ import annotations

import hashlib
import json
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from pathlib import Path

_BYO_DIR = Path("/var/lib/ligbox-wizard/onboarding_dns_byo_tokens")
_TTL_HOURS = 24 * 7


@dataclass
class ByoCloudflareSession:
    domain: str
    api_token: str
    zone_id: str


def _now() -> datetime:
    return datetime.now(timezone.utc)


def _vault_path(session_id: str, domain: str) -> Path:
    key = hashlib.sha256(f"{session_id}:{domain.lower()}".encode()).hexdigest()
    return _BYO_DIR / f"{key}.json"


def _purge_expired() -> None:
    if not _BYO_DIR.is_dir():
        return
    now = _now()
    for path in _BYO_DIR.glob("*.json"):
        try:
            data = json.loads(path.read_text(encoding="utf-8"))
            expires = datetime.fromisoformat(data["expires_at"])
            if expires.tzinfo is None:
                expires = expires.replace(tzinfo=timezone.utc)
            if now > expires:
                path.unlink(missing_ok=True)
        except (json.JSONDecodeError, KeyError, ValueError):
            path.unlink(missing_ok=True)


def save_byo_token(session_id: str, domain: str, api_token: str, zone_id: str) -> None:
    session_id = (session_id or "").strip()
    domain = domain.lower().strip().rstrip(".")
    if len(session_id) < 8:
        raise ValueError("Sessão inválida")
    if not api_token or not zone_id:
        raise ValueError("Token ou zone_id ausente")
    _BYO_DIR.mkdir(parents=True, exist_ok=True)
    _purge_expired()
    expires = _now() + timedelta(hours=_TTL_HOURS)
    _vault_path(session_id, domain).write_text(
        json.dumps(
            {
                "domain": domain,
                "api_token": api_token,
                "zone_id": zone_id,
                "expires_at": expires.isoformat(),
            }
        ),
        encoding="utf-8",
    )


def load_byo_token(session_id: str, domain: str) -> ByoCloudflareSession | None:
    session_id = (session_id or "").strip()
    domain = domain.lower().strip().rstrip(".")
    if len(session_id) < 8:
        return None
    _purge_expired()
    path = _vault_path(session_id, domain)
    if not path.is_file():
        return None
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        expires = datetime.fromisoformat(data["expires_at"])
        if expires.tzinfo is None:
            expires = expires.replace(tzinfo=timezone.utc)
        if _now() > expires:
            path.unlink(missing_ok=True)
            return None
        return ByoCloudflareSession(
            domain=data["domain"],
            api_token=data["api_token"],
            zone_id=data["zone_id"],
        )
    except (json.JSONDecodeError, KeyError, ValueError):
        path.unlink(missing_ok=True)
        return None


def clear_byo_token(session_id: str, domain: str) -> None:
    session_id = (session_id or "").strip()
    domain = domain.lower().strip().rstrip(".")
    if len(session_id) < 8:
        return
    _vault_path(session_id, domain).unlink(missing_ok=True)
