"""
Auto-signup for Kevros Agentic Identity Trust.

Zero-friction: if no API key is provided, signs up automatically and
caches the key in ~/.kevros/api_key. The agent gets a verifiable identity
without any human in the loop.

Used by: GovernanceClient, LangChain tools, CrewAI tools, OpenAI functions, MCP server.
"""

from __future__ import annotations

import json
import logging
import os
from pathlib import Path
from typing import Optional

import httpx

logger = logging.getLogger("kevros.auto_signup")

DEFAULT_GATEWAY_URL = "https://governance.taskhawktech.com"
_KEY_DIR = Path.home() / ".kevros"
_KEY_FILE = _KEY_DIR / "api_key"
_TIMEOUT = 15.0


def _read_cached_key() -> Optional[str]:
    """Read cached API key from ~/.kevros/api_key."""
    if _KEY_FILE.exists():
        key = _KEY_FILE.read_text().strip()
        if key.startswith("kvrs_"):
            return key
    return None


def _write_cached_key(api_key: str, meta: dict) -> None:
    """Cache API key and signup metadata to ~/.kevros/."""
    _KEY_DIR.mkdir(parents=True, exist_ok=True)
    _KEY_FILE.write_text(api_key)
    # Restrict permissions (owner read/write only)
    try:
        _KEY_FILE.chmod(0o600)
    except OSError:
        pass
    # Write metadata alongside
    meta_file = _KEY_DIR / "signup.json"
    meta_file.write_text(json.dumps(meta, indent=2))


def get_or_create_api_key(
    agent_id: str,
    gateway_url: str = DEFAULT_GATEWAY_URL,
    operator_email: str = "",
    operator_name: str = "",
) -> str:
    """
    Get an existing API key or auto-signup for a free one.

    Resolution order:
    1. KEVROS_API_KEY environment variable
    2. ~/.kevros/api_key file
    3. Auto-signup via POST /signup (creates key, caches it)

    Args:
        agent_id: Your agent's identifier (required for signup).
        gateway_url: Gateway URL (default: production).
        operator_email: Optional email for account recovery.
        operator_name: Optional legal entity name.

    Returns:
        API key string (starts with kvrs_).

    Raises:
        RuntimeError: If signup fails.
    """
    # 1. Environment variable (explicit override)
    env_key = os.environ.get("KEVROS_API_KEY", "").strip()
    if env_key and env_key.startswith("kvrs_"):
        return env_key

    # 2. Cached key file
    cached = _read_cached_key()
    if cached:
        return cached

    # 3. Auto-signup
    logger.info("No Kevros API key found — signing up for free tier (agent_id=%s)", agent_id)
    try:
        resp = httpx.post(
            f"{gateway_url.rstrip('/')}/signup",
            json={
                "agent_id": agent_id,
                "operator_email": operator_email,
                "operator_name": operator_name,
            },
            timeout=_TIMEOUT,
        )
        if resp.status_code == 200:
            data = resp.json()
            api_key = data["api_key"]
            _write_cached_key(api_key, {
                "agent_id": agent_id,
                "tier": data.get("tier", "free"),
                "monthly_limit": data.get("monthly_limit", 100),
                "rate_limit_per_minute": data.get("rate_limit_per_minute", 10),
                "gateway_url": gateway_url,
                "upgrade_url": data.get("upgrade_url", ""),
            })
            logger.info(
                "Kevros free tier activated: %d calls/mo, %d req/min. "
                "Key cached at %s",
                data.get("monthly_limit", 100),
                data.get("rate_limit_per_minute", 10),
                _KEY_FILE,
            )
            return api_key
        else:
            detail = resp.text
            try:
                detail = resp.json().get("detail", resp.text)
            except Exception:
                pass
            raise RuntimeError(f"Kevros signup failed (HTTP {resp.status_code}): {detail}")
    except httpx.HTTPError as e:
        raise RuntimeError(f"Kevros signup failed (network error): {e}") from e
