from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def _strip_inline_comment(line: str) -> str:
    return line.split("#", 1)[0].strip()


def _requirement_name(line: str) -> str:
    line = _strip_inline_comment(line)
    for operator in ("==", ">=", "<=", "~=", "!=", ">"):
        if operator in line:
            return line.split(operator, 1)[0].strip().lower()
    return line.lower()


def _requirement_names() -> set[str]:
    names = set()
    for raw_line in (ROOT / "requirements.txt").read_text(encoding="utf-8").splitlines():
        line = _strip_inline_comment(raw_line)
        if not line or line.startswith(("-", "--")):
            continue
        names.add(_requirement_name(line))
    return names


def test_requirements_have_version_specifiers():
    unpinned = []
    for raw_line in (ROOT / "requirements.txt").read_text(encoding="utf-8").splitlines():
        line = _strip_inline_comment(raw_line)
        if not line:
            continue
        if line.startswith(("-", "--")):
            continue
        if "@" in line:
            continue
        if not any(op in line for op in ("==", ">=", "<=", "~=", "!=", ">")):
            unpinned.append(line)

    assert unpinned == []


def test_audit_flagged_runtime_dependencies_have_import_evidence():
    requirements = _requirement_names()
    runtime_evidence = {
        "beautifulsoup4": [
            ("services/cosme_crawler.py", "from bs4 import BeautifulSoup"),
            ("services/momo_crawler.py", "from bs4 import BeautifulSoup"),
            ("services/trend_crawler.py", "from bs4 import BeautifulSoup"),
        ],
        "google-api-python-client": [
            ("services/google_drive_service.py", "from googleapiclient.discovery import build"),
        ],
        "google-generativeai": [
            ("services/gemini_service.py", "import google.generativeai as genai"),
            ("services/openclaw_strategist_service.py", "import google.generativeai as genai"),
        ],
        "python-pptx": [
            ("services/ppt_generator.py", "from pptx import Presentation"),
        ],
        "matplotlib": [
            ("routes/openclaw_bot_routes.py", "import matplotlib"),
            ("services/chart_generator_service.py", "import matplotlib"),
            ("services/ppt_generator.py", "import matplotlib"),
        ],
    }

    missing_packages = sorted(set(runtime_evidence) - requirements)
    assert missing_packages == []

    missing_evidence = []
    for package, locations in runtime_evidence.items():
        if not any(pattern in (ROOT / path).read_text(encoding="utf-8") for path, pattern in locations):
            missing_evidence.append(package)

    assert missing_evidence == []


def test_cli_ssh_helper_replaces_legacy_paramiko_dependency():
    requirements = _requirement_names()
    helper_source = (ROOT / "utils" / "ssh_helper.py").read_text(encoding="utf-8")

    assert "paramiko" not in requirements
    assert "subprocess.run" in helper_source
    assert '"ssh"' in helper_source
    assert "paramiko" not in helper_source


def test_pgvector_extension_uses_local_sqlalchemy_type_not_python_package():
    requirements = _requirement_names()
    ai_models_source = (ROOT / "database" / "ai_models.py").read_text(encoding="utf-8")
    migration_source = (ROOT / "migrations" / "009_pgvector_embedding.sql").read_text(encoding="utf-8")

    assert "pgvector" not in requirements
    assert "matplotlib-inline" not in requirements
    assert "class Vector(UserDefinedType)" in ai_models_source
    assert "CREATE EXTENSION IF NOT EXISTS vector" in migration_source
