#!/usr/bin/env python3
from __future__ import annotations

import argparse
import hashlib
import json
import shutil
from datetime import datetime, timezone
from pathlib import Path

TRUTH_FILES = [
    ("all.sh", "all.sh"),
    ("v1/step1.sh", "v1/step1.sh"),
    ("v1/step2.sh", "v1/step2.sh"),
    ("v1/step3.sh", "v1/step3.sh"),
    ("v1/step_ai.sh", "v1/step_ai.sh"),
    ("v1/step_diff.sh", "v1/step_diff.sh"),
    ("v1/step_git.sh", "v1/step_git.sh"),
    ("v1/step_vpn.sh", "v1/step_vpn.sh"),
]


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


def copy_file(source: Path, destination: Path) -> None:
    destination.parent.mkdir(parents=True, exist_ok=True)
    shutil.copy2(source, destination)
    if destination.suffix == ".sh":
        destination.chmod(destination.stat().st_mode | 0o755)


def build_manifest(source_root: Path) -> dict:
    imported_at = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
    manifest_files = []
    combined = hashlib.sha256()

    for source_rel, bundle_rel in TRUTH_FILES:
        source_path = source_root / source_rel
        digest = sha256_file(source_path)
        combined.update(f"{bundle_rel}:{digest}\n".encode("utf-8"))
        manifest_files.append(
            {
                "source_relpath": source_rel,
                "bundle_relpath": bundle_rel,
                "sha256": digest,
                "size": source_path.stat().st_size,
            }
        )

    return {
        "bundle_version": combined.hexdigest()[:16],
        "imported_at": imported_at,
        "source_dir": str(source_root),
        "file_count": len(manifest_files),
        "files": manifest_files,
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Import runtime bundle from /root/data/lehome_cli")
    parser.add_argument("--source", default="/root/data/lehome_cli", help="source truth directory")
    parser.add_argument(
        "--bundle-root",
        default=str(Path(__file__).resolve().parents[1] / "src" / "lehome_cli" / "bundle"),
        help="bundle output directory",
    )
    args = parser.parse_args()

    source_root = Path(args.source).resolve()
    bundle_root = Path(args.bundle_root).resolve()
    bundle_root.mkdir(parents=True, exist_ok=True)
    (bundle_root / "__init__.py").write_text('"""Runtime bundle imported from /root/data/lehome_cli."""\n', encoding="utf-8")

    missing = [source_rel for source_rel, _ in TRUTH_FILES if not (source_root / source_rel).is_file()]
    if missing:
        raise SystemExit(f"missing source files: {', '.join(missing)}")

    for old_file in [bundle_root / "all.sh", bundle_root / "manifest.json"]:
        if old_file.exists():
            old_file.unlink()
    old_v1 = bundle_root / "v1"
    if old_v1.exists():
        shutil.rmtree(old_v1)

    for source_rel, bundle_rel in TRUTH_FILES:
        source_path = source_root / source_rel
        bundle_path = bundle_root / bundle_rel
        copy_file(source_path, bundle_path)

    manifest = build_manifest(source_root)
    manifest_path = bundle_root / "manifest.json"
    manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8")

    print(f"source_root={source_root}")
    print(f"bundle_root={bundle_root}")
    print(f"bundle_version={manifest['bundle_version']}")
    for entry in manifest["files"]:
        print(f"synced {entry['source_relpath']} -> {entry['bundle_relpath']} [{entry['sha256'][:12]}]")
    return 0


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