#!/usr/bin/env python3
import argparse
from pathlib import Path

from script_common import find_node_app_root, resolve_repo_root, run, sha256_files


def main() -> int:
    parser = argparse.ArgumentParser(description="Cross-platform web/tauri publish helper")
    parser.add_argument("--target", choices=["web", "tauri"], default="web")
    parser.add_argument("--configuration", choices=["Release", "Debug"], default="Release")
    parser.add_argument("--tauri-bundles", choices=["none", "nsis", "msi"], default="none")
    parser.add_argument("--install-deps", action="store_true")
    parser.add_argument("--skip-install", action="store_true")
    parser.add_argument("--dry-run", action="store_true")
    parser.add_argument("--repo-root", default=None)
    parser.add_argument("--app-root", default=None, help="Relative or absolute app root with package.json")
    args = parser.parse_args()

    repo_root = resolve_repo_root(args.repo_root)
    app_root = find_node_app_root(repo_root, args.app_root)
    if app_root is None:
        print("Unable to locate app root (no unique package.json found).")
        return 2

    package_json = app_root / "package.json"
    lock_file = app_root / "package-lock.json"
    node_modules = app_root / "node_modules"
    deps_hash_file = node_modules / ".sdt-deps.sha256"
    expected_hash = sha256_files([package_json, lock_file])

    should_install = args.install_deps or not node_modules.exists()
    if not should_install and not args.skip_install:
        if not deps_hash_file.exists():
            should_install = True
        else:
            current = deps_hash_file.read_text(encoding="utf-8").strip()
            should_install = current != expected_hash
    if args.skip_install:
        should_install = False

    print(f"App root: {app_root}")
    print(f"Target: {args.target} ({args.configuration})")

    if should_install:
        install_args = ["ci", "--no-audit", "--fund=false"] if lock_file.exists() else ["install", "--no-audit", "--fund=false"]
        print("$ npm " + " ".join(install_args))
        if not args.dry_run:
            code = run("npm", install_args, app_root)
            if code != 0:
                if lock_file.exists() and install_args[0] == "ci":
                    print("npm ci failed (likely lockfile out of sync). Falling back to npm install...")
                    fallback_args = ["install", "--no-audit", "--fund=false"]
                    print("$ npm " + " ".join(fallback_args))
                    code = run("npm", fallback_args, app_root)
                    if code != 0:
                        return code
                else:
                    return code
            node_modules.mkdir(parents=True, exist_ok=True)
            deps_hash_file.write_text(expected_hash, encoding="utf-8")
    else:
        print("Skipping dependency install.")

    if args.target == "web":
        cmd = ["run", "build"]
        print("$ npm " + " ".join(cmd))
        if not args.dry_run:
            return run("npm", cmd, app_root)
        return 0

    tauri_cmd = ["run", "tauri", "build"]
    tauri_tail: list[str] = []
    if args.tauri_bundles == "none":
        tauri_tail.extend(["--no-bundle"])
    else:
        tauri_tail.extend(["--bundles", args.tauri_bundles])
    if args.configuration == "Debug":
        tauri_tail.append("--debug")
    if tauri_tail:
        tauri_cmd.extend(["--", *tauri_tail])

    print("$ npm " + " ".join(tauri_cmd))
    if not args.dry_run:
        return run("npm", tauri_cmd, app_root)

    return 0


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