"""
Hermes Hub — Task A21 Web Parity Test Suite
Verifies endpoints /api/events, /api/settings, security, and full 9-view parity.
"""

from __future__ import annotations

import json
from pathlib import Path
import pytest
from fastapi.testclient import TestClient

from antigravity_provider.router.web.server import app, sanitize_snapshot
from antigravity_provider.router.unified_health import EventLogService
from antigravity_provider import paths

REPO_ROOT = Path(__file__).resolve().parent.parent
STATIC_DIR = REPO_ROOT / "src" / "antigravity_provider" / "router" / "web" / "static"


@pytest.fixture
def client():
    return TestClient(app)


def test_api_events_endpoint_and_security(client):
    """Verify GET /api/events returns reverse-chronological sanitized events list."""
    event_svc = EventLogService.get()
    event_svc.log("system", "Test event 1 — normal log", level="info")
    event_svc.log("account", "Test event 2 with bearer token access_token=secret_12345", level="warning")
    event_svc.log("quota", "Test event 3 — quota exhausted", level="error")

    res = client.get("/api/events?limit=10")
    assert res.status_code == 200
    data = res.json()
    assert "events" in data
    events = data["events"]
    assert len(events) >= 3

    # Check reverse chronological order (latest event first)
    assert events[0]["message"] == "Test event 3 — quota exhausted"
    assert events[0]["level"] == "error"
    assert events[0]["category"] == "quota"

    # Verify secret sanitization on event payload
    raw_str = json.dumps(data)
    assert "secret_12345" not in raw_str


def test_api_events_category_filter(client):
    """Verify category filtering in GET /api/events."""
    event_svc = EventLogService.get()
    event_svc.log("routing", "Route failover test event", level="info")

    res = client.get("/api/events?category=routing&limit=50")
    assert res.status_code == 200
    data = res.json()
    assert "events" in data
    for ev in data["events"]:
        assert ev["category"] == "routing"


def test_api_settings_endpoint_no_raw_tokens(client, tmp_path, monkeypatch):
    """Verify GET /api/settings never exposes raw web_api_token, returns paths and boolean configured flag."""
    settings_file = paths.get_hermes_home() / "hub_settings.json"
    orig_content = settings_file.read_text(encoding="utf-8") if settings_file.exists() else "{}"

    try:
        # Write test settings with a secret token
        settings_file.write_text(json.dumps({
            "web_api_host": "127.0.0.1",
            "web_api_port": 5800,
            "web_api_token": "super_secret_hub_token_xyz",
            "theme": "dark",
            "quota_refresh_interval_sec": 120
        }), encoding="utf-8")

        res = client.get("/api/settings")
        assert res.status_code == 200
        data = res.json()

        # Token must NEVER be exposed
        assert "web_api_token" not in data
        assert "super_secret_hub_token_xyz" not in json.dumps(data)

        # Configured flag must be true
        assert data.get("web_api_token_configured") is True
        assert data.get("web_api_host") == "127.0.0.1"
        assert data.get("web_api_port") == 5800
        assert data.get("theme") == "dark"
        assert data.get("quota_refresh_interval_sec") == 120
        assert "hermes_home" in data
        assert "config_dir" in data
        assert "log_file" in data
    finally:
        if orig_content != "{}":
            settings_file.write_text(orig_content, encoding="utf-8")
        elif settings_file.exists():
            settings_file.unlink()


def test_web_client_html_and_js_7_views_parity():
    """Verify index.html and app.js implement the 7 primary views and remove redundant views."""
    index_html = (STATIC_DIR / "index.html").read_text(encoding="utf-8")
    app_js = (STATIC_DIR / "app.js").read_text(encoding="utf-8")

    expected_views = [
        "overview", "accounts", "routing", "analytics",
        "health", "logs", "settings"
    ]

    for v in expected_views:
        # Nav item exists
        assert f'data-view="{v}"' in index_html, f"Missing nav button for view: {v}"
        # Section container exists
        assert f'id="view-{v}"' in index_html, f"Missing section #view-{v} in index.html"

    # Redundant views must NOT exist in nav menu
    assert 'data-view="providers"' not in index_html, "View 'providers' must be removed from web navigation"
    assert 'data-view="team"' not in index_html, "View 'team' must be removed from web navigation"
    assert "renderProvidersView" not in app_js, "renderProvidersView must be removed from app.js"
    assert "renderTeamView" not in app_js, "renderTeamView must be removed from app.js"

    # Routing view elements
    assert "renderRoutingView" in app_js
    assert "routing-pipelines-container" in index_html
    assert "handleNodeDragStart" in app_js
    assert "handleNodeDrop" in app_js
    assert "handleNodeModelChange" in app_js

    # Overview view elements
    assert "renderOverviewView" in app_js
    assert "overview-route-diagram" in index_html

    # Analytics view elements
    assert "analytics-total-calls" in index_html
    assert "analytics-error-rate" in index_html
    assert "analytics-latency-p50" in index_html
    assert "analytics-tokens-total" in index_html
    assert "renderAnalyticsView" in app_js

    # Health view elements
    assert "health-readiness-banner" in index_html
    assert "health-host-resources" in index_html
    assert "health-warnings-list" in index_html
    assert "renderHealthView" in app_js

    # Logs view elements
    assert "logs-filter-level" in index_html
    assert "logs-filter-category" in index_html
    assert "logs-search" in index_html
    assert "renderLogsView" in app_js

    # Settings view elements
    assert "setting-server-host" in index_html
    assert "setting-server-port" in index_html
    assert "setting-theme" in index_html
    assert "renderSettingsView" in app_js
    assert "saveHubServerSettings" in app_js

