"""Interpreter and third-party closure binding for Task22 fork execution."""
from __future__ import annotations

import hashlib
import importlib
import importlib.metadata
import os
import pkgutil
import stat
import sys
import sysconfig
from pathlib import Path
from types import ModuleType
from typing import cast

EXPECTED_DISTRIBUTIONS = {
    "PyYAML": "6.0.3", "Pygments": "2.19.2", "annotated-types": "0.7.0",
    "attrs": "25.4.0", "brotlicffi": "1.2.0.1", "cffi": "2.0.0",
    "click": "8.3.1", "cryptography": "46.0.7", "httpx": "0.28.1",
    "idna": "3.15", "pydantic": "2.13.4", "pydantic_core": "2.46.4",
    "python-telegram-bot": "22.6", "pytz": "2025.2", "rich": "14.3.3",
    "setuptools": "81.0.0", "tornado": "6.5.7", "typing-inspection": "0.4.2",
    "typing_extensions": "4.15.0",
}
ROOT_FAMILIES = ("pydantic", "pydantic_core", "yaml", "telegram")
OPTIONAL_MODULES = {
    "pydantic.mypy", "pydantic.v1.mypy", "pydantic.v1._hypothesis_plugin",
}


class RuntimeSeal:
    def __init__(
        self,
        observed: dict[str, str],
        identities: dict[str, dict[str, object]],
        modules: dict[str, dict[str, object]],
        descriptors: list[int],
    ) -> None:
        self.observed: dict[str, str] = observed
        self.identities: dict[str, dict[str, object]] = identities
        self.modules: dict[str, dict[str, object]] = modules
        self._descriptors: list[int] = descriptors

    def close(self) -> None:
        while self._descriptors:
            os.close(self._descriptors.pop())


def _sha_descriptor(descriptor: int) -> str:
    _ = os.lseek(descriptor, 0, os.SEEK_SET)
    digest = hashlib.sha256()
    while block := os.read(descriptor, 1 << 20):
        digest.update(block)
    _ = os.lseek(descriptor, 0, os.SEEK_SET)
    return digest.hexdigest()


def _bind(path: Path, *, nofollow: bool = True) -> tuple[int, dict[str, object]]:
    flags = os.O_RDONLY | os.O_CLOEXEC
    if nofollow:
        flags |= os.O_NOFOLLOW
    descriptor = os.open(path, flags)
    pinned = os.fstat(descriptor)
    current = os.stat(path, follow_symlinks=not nofollow)
    keys = ("st_dev", "st_ino", "st_uid", "st_gid", "st_mode", "st_size")
    if not stat.S_ISREG(pinned.st_mode) or any(
        getattr(pinned, key) != getattr(current, key) for key in keys
    ):
        os.close(descriptor)
        raise RuntimeError(f"runtime closure identity changed while binding {path}")
    identity: dict[str, object] = {
        "path": str(path), "device": pinned.st_dev, "inode": pinned.st_ino,
        "uid": pinned.st_uid, "gid": pinned.st_gid,
        "mode": stat.S_IMODE(pinned.st_mode), "size": pinned.st_size,
        "sha256": _sha_descriptor(descriptor),
    }
    return descriptor, identity


def _preload_families() -> None:
    for root in ROOT_FAMILIES:
        package = importlib.import_module(root)
        paths = cast(list[str], getattr(package, "__path__", []))
        for found in pkgutil.walk_packages(paths, root + "."):
            if found.name not in OPTIONAL_MODULES:
                _ = importlib.import_module(found.name)


def _third_party_modules() -> dict[str, ModuleType]:
    purelib = Path(sysconfig.get_path("purelib")).resolve()
    package_map = importlib.metadata.packages_distributions()
    result: dict[str, ModuleType] = {}
    for name, module in sys.modules.items():
        distributions = package_map.get(name.partition(".")[0], ())
        if not set(distributions).intersection(EXPECTED_DISTRIBUTIONS):
            continue
        filename = getattr(module, "__file__", None)
        if isinstance(filename, str):
            try:
                _ = Path(filename).resolve().relative_to(purelib)
            except ValueError:
                continue
            result[name] = module
    return result


def _validate_distributions(modules: dict[str, ModuleType]) -> None:
    package_map = importlib.metadata.packages_distributions()
    observed: set[str] = set()
    for name in modules:
        observed.update(package_map.get(name.partition(".")[0], ()))
    unknown = observed.symmetric_difference(EXPECTED_DISTRIBUTIONS)
    failures = [f"unknown third-party distributions: {sorted(unknown)}"] if unknown else []
    for name, expected in EXPECTED_DISTRIBUTIONS.items():
        try:
            version = importlib.metadata.version(name)
        except importlib.metadata.PackageNotFoundError:
            version = "missing"
        if name in observed and version != expected:
            failures.append(f"{name}={version} (required {expected})")
    required = {"pydantic", "PyYAML", "python-telegram-bot"}
    if not required.issubset(observed):
        failures.append(f"required distributions absent: {sorted(required - observed)}")
    if failures:
        raise RuntimeError("dependency closure attestation failed: " + "; ".join(failures))


def attest_runtime(
    prefix_required: Path,
    base_required: Path,
    cfg_digest: str,
    dependencies: dict[str, str],
) -> RuntimeSeal:
    observed = {"sys.prefix": sys.prefix, "sys.base_prefix": sys.base_prefix}
    failures: list[str] = []
    if Path(sys.prefix) != prefix_required:
        failures.append(f"sys.prefix={sys.prefix} (required {prefix_required})")
    if Path(sys.base_prefix) != base_required:
        failures.append(f"sys.base_prefix={sys.base_prefix} (required {base_required})")
    for name, expected in dependencies.items():
        try:
            version = importlib.metadata.version(name)
        except importlib.metadata.PackageNotFoundError:
            version = "missing"
        observed[name] = version
        if version != expected:
            failures.append(f"{name}={version} (required {expected})")
    if failures:
        raise RuntimeError("runtime attestation failed: " + "; ".join(failures))
    descriptors: list[int] = []
    identities: dict[str, dict[str, object]] = {}
    try:
        for label, path, nofollow in (
            ("proc_exe", Path("/proc/self/exe"), False),
            ("venv_executable", prefix_required / "bin/python", False),
            ("pyvenv_cfg", prefix_required / "pyvenv.cfg", True),
        ):
            descriptor, identity = _bind(path, nofollow=nofollow)
            descriptors.append(descriptor)
            identities[label] = identity
        executable = identities["proc_exe"]
        if executable != {**identities["venv_executable"], "path": "/proc/self/exe"}:
            raise RuntimeError("running executable does not match the retained venv executable")
        if Path(sys.executable) != prefix_required / "bin/python":
            raise RuntimeError("sys.executable is outside the exact venv boundary")
        if identities["pyvenv_cfg"]["sha256"] != cfg_digest:
            raise RuntimeError("pyvenv.cfg bytes do not match the canonical pin")
        _preload_families()
        modules = _third_party_modules()
        _validate_distributions(modules)
        module_identities: dict[str, dict[str, object]] = {}
        by_path: dict[Path, tuple[int, dict[str, object]]] = {}
        for name, module in sorted(modules.items()):
            path = Path(cast(str, module.__file__)).resolve()
            binding = by_path.get(path)
            if binding is None:
                binding = _bind(path)
                by_path[path] = binding
                descriptors.append(binding[0])
            module_identities[name] = binding[1]
        return RuntimeSeal(observed, identities, module_identities, descriptors)
    except BaseException:
        while descriptors:
            os.close(descriptors.pop())
        raise
