"""MCP server — thin wrappers that delegate to clawdflare.lib.tools.

Tool names keep the clawdflare_ prefix for MCP (AI agents need namespaced tool names).

SECURITY MODEL:
  - Read tools use a config/env var token. Safe to call freely.
  - Write tools trigger a native OS PIN dialog. The user must physically authorize.
  - The AI agent never sees the write token or the PIN.
  - Multiple Cloudflare accounts supported — switch with clawdflare_use_account.
"""

from typing import Optional

from mcp.server.fastmcp import FastMCP

from clawdflare.lib import tools, vault

mcp = FastMCP("clawdflare")


# ---------------------------------------------------------------------------
# Account management
# ---------------------------------------------------------------------------

@mcp.tool()
async def clawdflare_accounts() -> list[dict]:
    """List all configured Cloudflare accounts.

    Shows account name, active status, token names from Cloudflare dashboard,
    and whether read/write tokens are configured.
    No secrets are exposed.
    """
    return vault.list_accounts()


@mcp.tool()
async def clawdflare_use_account(account: str) -> dict:
    """Switch the active Cloudflare account.

    All subsequent read/write operations will use this account's tokens.

    Args:
        account: Account name (e.g. "personal", "work").
    """
    vault.set_active_account(account)
    return {"active": account}


# ---------------------------------------------------------------------------
# Read tools (no authorization needed)
# ---------------------------------------------------------------------------

@mcp.tool()
async def clawdflare_zones() -> dict:
    """List all Cloudflare zones in the active account with status and plan info."""
    return await tools.zones()


@mcp.tool()
async def clawdflare_zone_settings(zone: str) -> dict:
    """Get all settings for a Cloudflare zone.

    Args:
        zone: Domain name (e.g. "example.com") or zone ID.
    """
    return await tools.zone_settings(zone)


@mcp.tool()
async def clawdflare_dns_records(zone: str) -> dict:
    """List DNS records for a zone.

    Args:
        zone: Domain name or zone ID.
    """
    return await tools.dns_records(zone)


@mcp.tool()
async def clawdflare_audit(zone: str) -> dict:
    """Audit a zone against opinionated security and performance best practices.

    Returns findings sorted by severity (critical first). Each finding includes
    the current value, recommended value, and reason for the recommendation.

    Args:
        zone: Domain name or zone ID.
    """
    return await tools.audit(zone)


@mcp.tool()
async def clawdflare_ssl_status(zone: str) -> dict:
    """Get a focused SSL/TLS configuration summary for a zone.

    Shows SSL mode, HTTPS enforcement, TLS version, HSTS, and HTTP/3 status.

    Args:
        zone: Domain name or zone ID.
    """
    return await tools.ssl_status(zone)


# ---------------------------------------------------------------------------
# Write tools (PIN-protected — user must authorize via native OS popup)
# ---------------------------------------------------------------------------

@mcp.tool()
async def clawdflare_fix(
    zone: str,
    setting: Optional[str] = None,
    dry_run: bool = True,
) -> dict:
    """Fix zone settings to match opinionated best practices.

    SECURITY: When dry_run=False, a native OS PIN dialog will appear.
    The user must enter their PIN to authorize the write. The AI agent
    cannot see the PIN or the write token.

    Defaults to dry_run=True so you can review changes first.

    Args:
        zone: Domain name or zone ID.
        setting: Optional single setting to fix (e.g. "ssl", "min_tls_version").
                 If omitted, fixes all non-compliant settings.
        dry_run: If True (default), shows what would change without applying.
    """
    return await tools.fix(zone, setting, dry_run)


@mcp.tool()
async def clawdflare_set_setting(zone: str, setting: str, value: str) -> dict:
    """Set a specific Cloudflare zone setting.

    SECURITY: A native OS PIN dialog will appear. The user must enter
    their PIN to authorize the write. The AI agent cannot see the PIN
    or the write token.

    Args:
        zone: Domain name or zone ID.
        setting: Setting ID (e.g. "ssl", "min_tls_version", "always_use_https").
        value: Value to set (e.g. "full", "1.2", "on").
    """
    return await tools.set_setting(zone, setting, value)


@mcp.tool()
async def clawdflare_purge_cache(
    zone: str,
    everything: bool = False,
    urls: Optional[list[str]] = None,
) -> dict:
    """Purge cached content for a zone.

    SECURITY: A native OS PIN dialog will appear. The user must enter
    their PIN to authorize the write. The AI agent cannot see the PIN
    or the write token.

    Either purge everything or specific URLs.

    Args:
        zone: Domain name or zone ID.
        everything: Purge all cached content.
        urls: List of specific URLs to purge.
    """
    return await tools.purge_cache(zone, everything, urls)


if __name__ == "__main__":
    mcp.run()
