from __future__ import annotations

import re
from collections import Counter
from pathlib import Path

import yaml

REPO_ROOT = Path(__file__).resolve().parents[3]

DIRECT_OLLAMA_URL_PATTERN = re.compile(
    r"""
    settings\.OLLAMA_URL
    | get_settings\(\)\.OLLAMA_URL
    | _get_settings\(\)\.OLLAMA_URL
    | _gs\(\)\.OLLAMA_URL
    | self\._settings\.OLLAMA_URL
    | getattr\([^\n]*["']OLLAMA_URL["']
    | OLLAMA_URL\s*=\s*os\.getenv
    | OLLAMA_URL\s*=\s*_get_settings\(\)\.OLLAMA_URL
    """,
    re.VERBOSE,
)

# Existing direct settings.OLLAMA_URL usage is legacy debt captured in
# docs/awooop/inventory/INV-10-ollama-call-sites.md. New call sites must go
# through a resolver, provider registry, or AwoooP EffectivePolicy path.
MAX_DIRECT_OLLAMA_URL_REFERENCES = {
    "apps/api/scripts/reembed_bge_m3.py": 1,
    "apps/api/src/api/v1/ai.py": 1,
    "apps/api/src/api/v1/health.py": 1,
    "apps/api/src/api/v1/rag.py": 1,
    "apps/api/src/hermes/nl_gateway.py": 1,
    "apps/api/src/routes/agent.py": 1,
    "apps/api/src/routes/health.py": 1,
    "apps/api/src/services/ai_providers/ollama.py": 3,
    "apps/api/src/services/chat_manager.py": 1,
    "apps/api/src/services/decision_fusion.py": 1,
    "apps/api/src/services/decision_fusion_adapter.py": 1,
    "apps/api/src/services/decision_manager.py": 2,
    "apps/api/src/services/drift_narrator_service.py": 1,
    "apps/api/src/services/heartbeat_report_service.py": 1,
    "apps/api/src/services/image_analysis_service.py": 1,
    "apps/api/src/services/intent_classifier.py": 1,
    "apps/api/src/services/knowledge_extractor_service.py": 1,
    "apps/api/src/services/log_summary_service.py": 1,
    "apps/api/src/services/model_version_probe.py": 2,
    "apps/api/src/services/nvidia_provider.py": 3,
    "apps/api/src/services/ollama_auto_recovery.py": 2,
    "apps/api/src/services/ollama_failover_manager.py": 3,
    "apps/api/src/services/openclaw.py": 4,
}

APPROVED_ROUTING_MODULES = {
    "apps/api/src/services/ollama_endpoint_resolver.py",
}


def _iter_python_files() -> list[Path]:
    roots = [
        REPO_ROOT / "apps/api/src",
        REPO_ROOT / "apps/api/scripts",
    ]
    files: list[Path] = []
    for root in roots:
        files.extend(path for path in root.rglob("*.py") if "__pycache__" not in path.parts)
    return sorted(files)


def _direct_ollama_reference_counts() -> Counter[str]:
    counts: Counter[str] = Counter()
    for path in _iter_python_files():
        rel_path = path.relative_to(REPO_ROOT).as_posix()
        if rel_path in APPROVED_ROUTING_MODULES:
            continue
        for line in path.read_text(encoding="utf-8").splitlines():
            if line.lstrip().startswith("#"):
                continue
            matches = sum(1 for _ in DIRECT_OLLAMA_URL_PATTERN.finditer(line))
            if matches:
                counts[rel_path] += matches
    return counts


def test_no_new_direct_ollama_url_call_sites() -> None:
    counts = _direct_ollama_reference_counts()
    unexpected = sorted(set(counts) - set(MAX_DIRECT_OLLAMA_URL_REFERENCES))
    increased = {
        path: (counts[path], MAX_DIRECT_OLLAMA_URL_REFERENCES[path])
        for path in sorted(set(counts) & set(MAX_DIRECT_OLLAMA_URL_REFERENCES))
        if counts[path] > MAX_DIRECT_OLLAMA_URL_REFERENCES[path]
    }

    assert not unexpected, (
        "New direct OLLAMA_URL call sites must be routed through a resolver, "
        "provider registry, or AwoooP EffectivePolicy first: "
        f"{unexpected}"
    )
    assert not increased, (
        "Direct OLLAMA_URL references increased. Update the code to use an "
        f"approved routing path instead: {increased}"
    )


def test_prod_ollama_env_matches_configmap_source_of_truth() -> None:
    configmap_path = REPO_ROOT / "k8s/awoooi-prod/04-configmap.yaml"
    deployment_path = REPO_ROOT / "k8s/awoooi-prod/06-deployment-api.yaml"

    configmap = yaml.safe_load(configmap_path.read_text(encoding="utf-8"))
    deployment_docs = list(yaml.safe_load_all(deployment_path.read_text(encoding="utf-8")))
    deployment = next(doc for doc in deployment_docs if doc.get("kind") == "Deployment")

    expected = {
        key: configmap["data"][key]
        for key in ("OLLAMA_URL", "OLLAMA_SECONDARY_URL", "OLLAMA_FALLBACK_URL")
    }

    containers = deployment["spec"]["template"]["spec"]["containers"]
    api_container = next(container for container in containers if container["name"] == "api")
    actual = {
        env["name"]: env["value"]
        for env in api_container["env"]
        if env["name"] in expected
    }

    assert actual == expected
