from __future__ import annotations

import importlib.util
from pathlib import Path
from types import ModuleType
from typing import Protocol, cast


EVIDENCE_ROOT = Path(__file__).resolve().parents[3]
REPOSITORY = Path("/home/cube/projects/richard/hermes-agent")
SEALER_PATH = EVIDENCE_ROOT / ".omo/senpi-task/task26/seal_dualcoach_provider_auth_candidate.py"
GATE18_NODE = "tests/gateway/test_nutrition_coaching.py"
GATE19_ADVERSARIAL_TEST = "tests/gateway/test_telegram_room_bootstrap_adversarial.py"


class _SealerModule(Protocol):
    CORE_SOURCE_FILES: tuple[str, ...]
    PYTEST_STARTUP_FILES: tuple[str, ...]

    def candidate_source_files(self, repository: Path) -> tuple[str, ...]: ...

    def gate18_source_files(self, repository: Path) -> tuple[str, ...]: ...

    def sealed_source_entries(self, repository: Path) -> list[dict[str, object]]: ...

    def source_entry(self, root: Path, relative: str) -> dict[str, object]: ...


def _load_sealer() -> _SealerModule:
    specification = importlib.util.spec_from_file_location(
        "seal_dualcoach_provider_auth_candidate_test_module", SEALER_PATH
    )
    assert specification is not None and specification.loader is not None
    module = importlib.util.module_from_spec(specification)
    assert isinstance(module, ModuleType)
    specification.loader.exec_module(module)
    return cast(_SealerModule, cast(object, module))


def test_gate18_source_closure_seals_pytest_startup_and_gateway_discovery_inputs() -> None:
    sealer = _load_sealer()

    source_paths = sealer.candidate_source_files(REPOSITORY)
    expected_gateway_tests = tuple(
        sorted(
            path.relative_to(REPOSITORY).as_posix()
            for path in (REPOSITORY / "tests/gateway").rglob("test_*.py")
            if path.is_file()
        )
    )
    expected_paths = tuple(
        dict.fromkeys(
            (
                *sealer.CORE_SOURCE_FILES,
                *sealer.PYTEST_STARTUP_FILES,
                *expected_gateway_tests,
            )
        )
    )

    assert sealer.gate18_source_files(REPOSITORY) == (
        *sealer.PYTEST_STARTUP_FILES,
        *expected_gateway_tests,
    )
    assert source_paths == expected_paths
    assert len(source_paths) == len(set(source_paths))
    assert GATE18_NODE in source_paths
    assert GATE19_ADVERSARIAL_TEST in source_paths
    assert sealer.sealed_source_entries(REPOSITORY) == [
        sealer.source_entry(REPOSITORY, relative) for relative in expected_paths
    ]
