#!/usr/bin/env python3
"""Stdlib-only isolated bootstrap for one frozen Task26 evidence bundle."""
from __future__ import annotations

import hashlib
import json
import os
import shutil
import stat
import subprocess
import sys
import tempfile
from pathlib import Path


def _sha(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as stream:
        for chunk in iter(lambda: stream.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def _private(path: Path, directory: bool = False) -> None:
    info = path.lstat()
    expected = stat.S_ISDIR if directory else stat.S_ISREG
    modes = {0o700, 0o500} if directory else {0o600, 0o400}
    if stat.S_ISLNK(info.st_mode) or not expected(info.st_mode) or stat.S_IMODE(info.st_mode) not in modes:
        raise ValueError(f"unsafe frozen path: {path}")


def _scan(root: Path) -> None:
    _private(root, True)
    pending = [root]
    while pending:
        directory = pending.pop()
        for entry in os.scandir(directory):
            path = Path(entry.path)
            if path.is_symlink():
                raise ValueError("frozen bundle contains a symlink")
            if path.is_dir():
                _private(path, True)
                pending.append(path)
            else:
                _private(path)


def main() -> int:
    if len(sys.argv) != 2 or not sys.flags.isolated:
        print(json.dumps({"status": "TASK26_BOOTSTRAP_FAIL", "reason": "isolated invocation required"}), file=sys.stderr)
        return 1
    bundle = Path(sys.argv[1]).absolute()
    temporary: Path | None = None
    try:
        _scan(bundle)
        expected_path = bundle / "sealed-expected-state.json"
        expected = json.loads(expected_path.read_text(encoding="utf-8"))
        unsigned = {key: value for key, value in expected.items() if key != "document_sha256"}
        canonical = json.dumps(unsigned, ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False).encode()
        if expected.get("document_sha256") != hashlib.sha256(canonical).hexdigest():
            raise ValueError("sealed expected-state digest differs")
        bound_wheels: dict[str, Path] = {}
        for label in ("hermes_wheel", "profile_wheel"):
            filename = str(expected[label]["filename"])
            matches = [
                path
                for path in bundle.rglob(filename)
                if path.is_file() and not path.is_symlink()
            ]
            if len(matches) != 1:
                raise ValueError(f"sealed {label} cardinality differs")
            path = matches[0]
            _private(path)
            if _sha(path) != expected[label]["sha256"]:
                raise ValueError(f"sealed {label} differs")
            bound_wheels[label] = path
        hermes = bound_wheels["hermes_wheel"]
        profile = bound_wheels["profile_wheel"]
        wheelhouse = bundle / "wheelhouse"
        dependency_paths: list[Path] = []
        entries = expected["wheelhouse"]["entries"]
        if entries:
            _private(wheelhouse, True)
            for row in entries:
                relative = Path(row["relative_path"])
                if relative.is_absolute() or ".." in relative.parts:
                    raise ValueError("wheelhouse path is invalid")
                path = wheelhouse / relative
                _private(path)
                if _sha(path) != row["sha256"] or path.stat().st_size != row["size"]:
                    raise ValueError("wheelhouse entry differs")
                dependency_paths.append(path)
        temporary = Path(tempfile.mkdtemp(prefix="task26-frozen-bootstrap-"))
        temporary.chmod(0o700)
        cwd = temporary / "cwd"
        cwd.mkdir(mode=0o700)
        venv = temporary / "venv"
        environment = {key: value for key, value in os.environ.items() if not key.startswith(("PYTHON", "PIP"))}
        environment.update({"PYTHONNOUSERSITE": "1", "PIP_NO_INDEX": "1", "PIP_CONFIG_FILE": os.devnull})
        subprocess.run([sys.executable, "-I", "-m", "venv", str(venv)], cwd=cwd, env=environment, check=True, capture_output=True)
        venv.chmod(0o700)
        python = venv / "bin/python"
        subprocess.run(
            [str(python), "-I", "-m", "pip", "install", "--no-index", "--no-deps", "--no-compile", *(str(path) for path in dependency_paths), str(profile), str(hermes)],
            cwd=cwd,
            env=environment,
            check=True,
            capture_output=True,
        )
        command = [str(python), "-I", "-m", "gateway.platforms.task26_final_state", str(bundle), str(expected_path), "--hermes-wheel", str(hermes), "--profile-wheel", str(profile)]
        if entries:
            command.extend(("--wheelhouse", str(wheelhouse)))
        completed = subprocess.run(command, cwd=cwd, env=environment, check=True, capture_output=True, text=True)
        result = json.loads(completed.stdout)
        output = {
            "schema": "task26-frozen-bootstrap-result-v1",
            "status": "TASK26_FROZEN_BOOTSTRAP_PASS",
            "expected_state_sha256": _sha(expected_path),
            "sealed_wheels": {
                "hermes_wheel_sha256": _sha(hermes),
                "profile_wheel_sha256": _sha(profile),
            },
            "verifier_result": result,
        }
        unsigned = json.dumps(
            output,
            ensure_ascii=False,
            sort_keys=True,
            separators=(",", ":"),
            allow_nan=False,
        ).encode()
        output["output_sha256"] = hashlib.sha256(unsigned).hexdigest()
        print(json.dumps(output, sort_keys=True, separators=(",", ":")))
        return 0
    except Exception as exc:
        print(json.dumps({"status": "TASK26_BOOTSTRAP_FAIL", "reason": str(exc)}, sort_keys=True), file=sys.stderr)
        return 1
    finally:
        if temporary is not None and temporary.exists():
            for path in temporary.rglob("*"):
                try:
                    if not path.is_symlink():
                        path.chmod(0o700 if path.is_dir() else 0o600)
                except OSError:
                    pass
            shutil.rmtree(temporary)


if __name__ == "__main__":
    raise SystemExit(main())
