#!/usr/bin/env python3
"""Build the immutable BEE release manifest used by worker health checks."""

from __future__ import annotations

import hashlib
import json
from pathlib import Path
import sys


MANIFEST_NAME = "bee-runtime-manifest.json"
EXCLUDED_PARTS = {".git", ".worktrees", "__pycache__", "tests", "logs"}


def _runtime_files(release: Path) -> dict[str, str]:
    files: dict[str, str] = {}
    for path in sorted(release.rglob("*")):
        relative = path.relative_to(release)
        if (
            not path.is_file()
            or relative.name == MANIFEST_NAME
            or any(part in EXCLUDED_PARTS for part in relative.parts)
            or relative.name.startswith(".env")
        ):
            continue
        files[relative.as_posix()] = hashlib.sha256(path.read_bytes()).hexdigest()
    return files


def build_manifest(release: Path) -> dict[str, object]:
    files = _runtime_files(release)
    tree = "".join(f"{path}\0{digest}\n" for path, digest in files.items()).encode()
    return {
        "manifest_version": "bee-runtime-manifest-v1",
        "tree_sha256": hashlib.sha256(tree).hexdigest(),
        "files": files,
    }


def main() -> None:
    if len(sys.argv) != 2:
        raise SystemExit("Usage: build_runtime_manifest.py <bee-release-dir>")
    release = Path(sys.argv[1]).resolve()
    if not (release / "init.inc.php").is_file():
        raise SystemExit("BEE release must contain init.inc.php")
    manifest = build_manifest(release)
    (release / MANIFEST_NAME).write_bytes(
        json.dumps(manifest, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode()
        + b"\n"
    )


if __name__ == "__main__":
    main()
