#!/usr/bin/env python3
import argparse
import hashlib
import json
import os
import zipfile
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]

EXCLUDED_DIRS = {
    ".cache",
    ".git",
    ".updates",
    "__pycache__",
    "config",
    "data",
    "dist",
}

EXCLUDED_FILES = {
    ".restart_requested",
    "api_calls.log",
    "api_usage.json",
    "airlabs_usage.json",
    "close.txt",
    "current_overhead.json",
    "current_tracked.json",
    "farthest.txt",
    "flight_counter.json",
    "flight_counter.json.migrated",
    "flightaware_usage.json",
    "tracked_flight.json",
    "wifi_connect.log",
}


def include(path):
    relative = path.relative_to(ROOT)
    if any(part in EXCLUDED_DIRS for part in relative.parts):
        return False
    if path.name in EXCLUDED_FILES:
        return False
    if path.suffix in {".bak", ".log", ".migrated", ".pyc", ".tmp"}:
        return False
    return True


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


def main():
    parser = argparse.ArgumentParser(description="Build a Plane Tracker remote update")
    parser.add_argument("--version", required=True, help="Semantic version, for example 1.4.0")
    parser.add_argument("--base-url", required=True, help="HTTPS folder where releases are hosted")
    parser.add_argument("--output", default="dist", help="Output directory")
    parser.add_argument("--notes", default="", help="Short release notes")
    args = parser.parse_args()

    if not args.base_url.lower().startswith("https://"):
        parser.error("--base-url must begin with https://")

    output = (ROOT / args.output).resolve()
    output.mkdir(parents=True, exist_ok=True)
    (ROOT / "VERSION").write_text(args.version.strip() + "\n", encoding="utf-8")

    zip_name = f"plane-tracker-{args.version}.zip"
    zip_path = output / zip_name
    with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
        for path in ROOT.rglob("*"):
            if path.is_file() and include(path):
                zf.write(path, path.relative_to(ROOT).as_posix())

    manifest = {
        "version": args.version,
        "url": f"{args.base_url.rstrip('/')}/{zip_name}",
        "sha256": sha256(zip_path),
        "release_notes": args.notes,
    }
    manifest_path = output / "manifest.json"
    manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")

    print(f"Built: {zip_path}")
    print(f"Manifest: {manifest_path}")
    print(f"SHA-256: {manifest['sha256']}")


if __name__ == "__main__":
    main()
