#!/usr/bin/env -S python3 -I
"""A stand-in for the datasets repository's scripts/push (flyloft's tier one): the committed-checkout guard, the
output's files copied to $FLYLOFT_CAMPAIGN/hub/<org>/<name>/candidate-<tree>/ in place of the Hub, then the manifest
(`file <path> <size> <sha256>` per file) and `commit: <sha>`, as the real push prints them."""

import hashlib
import os
import shutil
import subprocess
import sys
from pathlib import Path


def main() -> int:
    if len(sys.argv) != 3:
        print("usage: scripts/push <name> <output dir>", file=sys.stderr)
        return 2
    name, out = sys.argv[1], Path(sys.argv[2]).resolve()
    root = Path(__file__).resolve().parents[1]
    os.chdir(root)
    try:
        status = subprocess.run(
            ["git", "status", "--porcelain", "--ignored", "--untracked-files=all", "--", f"datasets/{name}"],
            capture_output=True,
            text=True,
            check=True,
        ).stdout
    except (OSError, subprocess.CalledProcessError) as e:
        print(f"scripts/push: git status failed: {e}", file=sys.stderr)
        return 1
    if status.strip():
        print(f"datasets/{name} has uncommitted changes; commit them first", file=sys.stderr)
        return 1
    tree = subprocess.run(
        [sys.executable, "-I", "scripts/check.py", "--tree", f"datasets/{name}"],
        capture_output=True,
        text=True,
        check=True,
    ).stdout.strip()
    org = next(
        line.split("=", 1)[1].strip().strip('"')
        for line in (root / "hub.toml").read_text().splitlines()
        if line.startswith("org")
    )
    files = sorted(
        p
        for p in out.rglob("*")
        if p.is_file() and not any(part.startswith(".") for part in p.relative_to(out).parts)
    )
    if not files:
        print(f"{sys.argv[2]} holds no files to push", file=sys.stderr)
        return 1
    dest = Path(os.environ["FLYLOFT_CAMPAIGN"]) / "hub" / org / name / f"candidate-{tree}"
    shutil.rmtree(dest, ignore_errors=True)
    dest.mkdir(parents=True)
    manifest = []
    for p in files:
        rel = p.relative_to(out)
        (dest / rel).parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(p, dest / rel)
        manifest.append(f"file {rel.as_posix()} {p.stat().st_size} {hashlib.sha256(p.read_bytes()).hexdigest()}")
    for line in manifest:
        print(line)
    print(f"commit: {hashlib.sha1('\n'.join(manifest).encode()).hexdigest()}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
