from __future__ import annotations

import importlib


preflight = importlib.import_module("scripts.postgres_dev_preflight")


def test_run_preflight_rejects_non_postgres_database_url(monkeypatch):
    monkeypatch.setenv("SCHEMA_MANAGEMENT_MODE", "migrations")

    results = preflight.run_preflight(
        database_url="sqlite:///./mvp_cc.db",
        base_url=None,
        require_rabbitmq=False,
    )

    assert len(results) == 1
    assert results[0].name == "database_url"
    assert results[0].ok is False


def test_run_preflight_requires_migrations_mode(monkeypatch):
    monkeypatch.setenv("SCHEMA_MANAGEMENT_MODE", "legacy")

    results = preflight.run_preflight(
        database_url="postgresql://mvp:mvp@localhost:5432/mvpcc",
        base_url=None,
        require_rabbitmq=False,
    )

    assert [item.name for item in results] == ["database_url", "schema_management_mode"]
    assert results[-1].ok is False


def test_run_preflight_passes_with_http_and_rabbitmq(monkeypatch):
    monkeypatch.setenv("SCHEMA_MANAGEMENT_MODE", "migrations")
    monkeypatch.setenv("EVENT_BUS_ENABLED", "1")
    monkeypatch.setenv("EVENT_BUS_URL", "amqp://guest:guest@localhost:5672/")

    monkeypatch.setattr(
        preflight,
        "_check_tcp_endpoint",
        lambda name, url, default_port: preflight.CheckResult(name, True, f"{default_port} ok"),
    )
    monkeypatch.setattr(
        preflight,
        "_check_database_connection",
        lambda database_url: preflight.CheckResult("database_connection", True, "SELECT 1 succeeded"),
    )
    monkeypatch.setattr(
        preflight,
        "_check_schema_migrations",
        lambda database_url: preflight.CheckResult("schema_migrations", True, "applied=18/18"),
    )
    monkeypatch.setattr(
        preflight,
        "_http_preflight_checks",
        lambda base_url: [
            preflight.CheckResult("gateway_health", True, "status=200"),
            preflight.CheckResult("auth_health", True, "status=200"),
        ],
    )

    results = preflight.run_preflight(
        database_url="postgresql://mvp:mvp@localhost:5432/mvpcc",
        base_url="http://127.0.0.1:8080",
        require_rabbitmq=False,
    )

    assert all(item.ok for item in results)
    assert any(item.name == "rabbitmq_tcp" for item in results)
    assert any(item.name == "gateway_health" for item in results)


def test_main_returns_nonzero_when_preflight_fails(monkeypatch, capsys):
    monkeypatch.setattr(
        preflight,
        "run_preflight",
        lambda **kwargs: [preflight.CheckResult("database_connection", False, "boom")],
    )
    monkeypatch.setattr(
        preflight.argparse.ArgumentParser,
        "parse_args",
        lambda self: type(
            "Args",
            (),
            {
                "env_file": [],
                "database_url": "postgresql://mvp:mvp@localhost:5432/mvpcc",
                "base_url": "",
                "require_rabbitmq": False,
                "json": False,
            },
        )(),
    )

    exit_code = preflight.main()
    output = capsys.readouterr().out

    assert exit_code == 1
    assert "[FAIL] PostgreSQL dev preflight failed" in output


def test_http_preflight_uses_admin_login_token_for_read_checks(monkeypatch):
    monkeypatch.setenv("ALLOW_LEGACY_HEADER_AUTH", "0")
    monkeypatch.setenv("EVENT_BUS_ENABLED", "0")
    monkeypatch.setenv("ASTERISK_BRIDGE_ENABLED", "0")
    monkeypatch.setattr(preflight, "issue_app_token", lambda **kwargs: "ops-token")

    recorded_headers = {}

    class FakeResponse:
        def __init__(self, status_code, payload):
            self.status_code = status_code
            self._payload = payload

        def json(self):
            return self._payload

    class FakeClient:
        def __init__(self, *args, **kwargs):
            pass

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def get(self, path, headers=None):
            if path == "/health":
                return FakeResponse(200, {"status": "ok"})
            if path == "/registry":
                return FakeResponse(200, {"services": {name: {} for name in preflight.REQUIRED_PROXY_HEALTH_SERVICES}})
            if path.startswith("/proxy/") and path.endswith("/health"):
                return FakeResponse(200, {"status": "ok"})
            if path in {
                "/proxy/routing/queues",
                "/proxy/voice/integrations/voice/events?limit=1",
                "/proxy/whatsapp/integrations/whatsapp/threads",
            }:
                recorded_headers[path] = dict(headers or {})
                return FakeResponse(200, [])
            raise AssertionError(f"Unexpected GET path: {path}")

        def post(self, path, json=None):
            if path == "/proxy/auth/auth/login":
                return FakeResponse(200, {"access_token": "login-token"})
            raise AssertionError(f"Unexpected POST path: {path}")

    monkeypatch.setattr(preflight.httpx, "Client", FakeClient)

    results = preflight._http_preflight_checks("http://127.0.0.1:18080")

    assert all(item.ok for item in results)
    assert recorded_headers["/proxy/routing/queues"] == {"Authorization": "Bearer login-token"}
    assert recorded_headers["/proxy/voice/integrations/voice/events?limit=1"] == {"Authorization": "Bearer login-token"}
    assert recorded_headers["/proxy/whatsapp/integrations/whatsapp/threads"] == {"Authorization": "Bearer login-token"}
