"""Unit tests for gitea dep provider path (phase drone).

Tests: _enrich_deps_with_sso routing for gitea, recipe_meta.py loading for gitea and drone,
the SCM-configured test's assertions (parametrized against mock redirect URLs). No real
network calls or container execs — the gitea/drone setup logic is integration-tested by the
real CI run (M1 build).
"""

from __future__ import annotations

import os
import sys
import types

import pytest

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "runner"))
from harness import meta as meta_mod  # noqa: E402

TESTS_DIR = os.path.join(os.path.dirname(__file__), "..")


# ---------------------------------------------------------------------------
# recipe_meta.py loading for gitea and drone
# ---------------------------------------------------------------------------


def _load(recipe: str):
    return meta_mod.load(recipe, tests_dir=TESTS_DIR)


def test_gitea_recipe_meta_health():
    """gitea recipe_meta.py declares the correct health path and OK codes."""
    m = _load("gitea")
    assert m.HEALTH_PATH == "/api/healthz"
    assert 200 in m.HEALTH_OK


def test_gitea_recipe_meta_extra_env():
    """gitea EXTRA_ENV returns sqlite3 COMPOSE_FILE and relaxed access controls."""
    m = _load("gitea")
    ctx = types.SimpleNamespace(
        domain="gite-abc123.ci.commoninternet.net", base_url="", meta=m, deps={}, op=None
    )
    env = meta_mod.extra_env(m, ctx)
    assert "compose.sqlite3.yml" in env.get("COMPOSE_FILE", "")
    assert env.get("GITEA_REQUIRE_SIGNIN_VIEW") == "false"
    assert env.get("GITEA_DISABLE_REGISTRATION") == "false"


def test_drone_recipe_meta_deps():
    """drone recipe_meta.py declares DEPS = ['gitea']."""
    m = _load("drone")
    assert "gitea" in m.DEPS


def test_drone_recipe_meta_health():
    """drone recipe_meta.py declares the correct health path."""
    m = _load("drone")
    assert m.HEALTH_PATH == "/healthz"
    assert 200 in m.HEALTH_OK


# ---------------------------------------------------------------------------
# _enrich_deps_with_sso routing for gitea (stub — no real container calls)
# ---------------------------------------------------------------------------


def _fake_setup_gitea_oauth(provider_domain, parent_domain):
    return {
        "admin_user": "ci_admin",
        "admin_password": "testpassword",
        "client_id": "abc-def-123",
        "client_secret": "secret-xyz",
    }


def test_enrich_deps_routes_gitea(monkeypatch):
    """_enrich_deps_with_sso returns a correctly shaped entry for the gitea dep."""

    sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "runner"))
    # Import the orchestrator; monkeypatch sso.setup_gitea_oauth so no real deploy happens
    import run_recipe_ci
    from harness import sso

    monkeypatch.setattr(sso, "setup_gitea_oauth", _fake_setup_gitea_oauth)

    deps_list = [{"recipe": "gitea", "domain": "gite-aabbcc.ci.commoninternet.net"}]
    result = run_recipe_ci._enrich_deps_with_sso(
        "drone", "dron-112233.ci.commoninternet.net", deps_list
    )

    assert "gitea" in result
    entry = result["gitea"]
    assert entry["recipe"] == "gitea"
    assert entry["domain"] == "gite-aabbcc.ci.commoninternet.net"
    assert entry["client_id"] == "abc-def-123"
    assert entry["client_secret"] == "secret-xyz"
    assert entry["admin_user"] == "ci_admin"


def test_enrich_deps_gitea_does_not_call_keycloak_path(monkeypatch):
    """_enrich_deps_with_sso for gitea does NOT call setup_keycloak_realm."""
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "runner"))
    import run_recipe_ci
    from harness import sso

    monkeypatch.setattr(sso, "setup_gitea_oauth", _fake_setup_gitea_oauth)

    called_keycloak = []
    monkeypatch.setattr(
        sso,
        "setup_keycloak_realm",
        lambda *a, **kw: called_keycloak.append(True) or {},
    )

    deps_list = [{"recipe": "gitea", "domain": "gite-aabbcc.ci.commoninternet.net"}]
    run_recipe_ci._enrich_deps_with_sso("drone", "dron-112233.ci.commoninternet.net", deps_list)
    assert not called_keycloak, "setup_keycloak_realm must not be called for gitea dep"


# ---------------------------------------------------------------------------
# SCM-configured test assertions (parametrized against mock URL scenarios)
# ---------------------------------------------------------------------------


@pytest.mark.parametrize(
    "location_url,gitea_domain,client_id,expect_pass",
    [
        # Correct redirect: Location header points to gitea dep's authorize endpoint with matching client_id
        (
            "https://gite-aabbcc.ci.commoninternet.net/login/oauth/authorize?client_id=abc-123&redirect_uri=x",
            "gite-aabbcc.ci.commoninternet.net",
            "abc-123",
            True,
        ),
        # Wrong domain: drone redirected to production gitea, not the dep
        (
            "https://git.autonomic.zone/login/oauth/authorize?client_id=abc-123",
            "gite-aabbcc.ci.commoninternet.net",
            "abc-123",
            False,
        ),
        # Wrong path: not the OAuth authorize endpoint (e.g. gitea's /user/login after full-redirect-follow)
        (
            "https://gite-aabbcc.ci.commoninternet.net/user/login?client_id=abc-123",
            "gite-aabbcc.ci.commoninternet.net",
            "abc-123",
            False,
        ),
        # Wrong client_id: drone is using a different OAuth app
        (
            "https://gite-aabbcc.ci.commoninternet.net/login/oauth/authorize?client_id=wrong-id",
            "gite-aabbcc.ci.commoninternet.net",
            "abc-123",
            False,
        ),
    ],
)
def test_scm_redirect_assertions(location_url, gitea_domain, client_id, expect_pass):
    """Parametrized verification of the SCM-configured test assertion logic (no HTTP calls).

    Tests the URL assertions against the Location header from drone's first 303 redirect
    (per ADV-drone-01 fix: _CaptureOneRedirect stops after drone's hop, not gitea's).
    """
    import urllib.parse

    parsed = urllib.parse.urlparse(location_url)
    params = urllib.parse.parse_qs(parsed.query)

    checks = [
        parsed.scheme == "https",
        parsed.netloc == gitea_domain,
        parsed.path == "/login/oauth/authorize",
        params.get("client_id", [None])[0] == client_id,
    ]
    all_pass = all(checks)
    assert all_pass == expect_pass, (
        f"Expected {'pass' if expect_pass else 'fail'} for URL {location_url!r}; checks: {checks}"
    )
