from __future__ import annotations

import argparse
import os
import sys
from pathlib import Path

try:
    from huggingface_hub import snapshot_download
except ImportError as exc:
    raise SystemExit(
        "Missing dependency: huggingface_hub. Install dependencies with `pip install -r requirements.txt`."
    ) from exc

from common import load_model_card


def main() -> int:
    parser = argparse.ArgumentParser(description="Download a Hugging Face model from a model card.")
    parser.add_argument("card_id", help="Model card id, for example qwen3-4b-instruct-2507")
    parser.add_argument(
        "--local-dir",
        help="Override destination directory. Defaults to the card storage_path.",
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Print what would be downloaded without downloading files.",
    )
    parser.add_argument(
        "--allow-pattern",
        action="append",
        dest="allow_patterns",
        help="Optional Hugging Face allow pattern. Can be passed multiple times.",
    )
    parser.add_argument(
        "--ignore-pattern",
        action="append",
        dest="ignore_patterns",
        default=["*.msgpack", "*.h5", "*.ot"],
        help="Optional Hugging Face ignore pattern. Can be passed multiple times.",
    )
    args = parser.parse_args()

    card = load_model_card(args.card_id)
    repo_id = card.get("upstream_id")
    if not repo_id:
        print(f"Model card `{args.card_id}` has no upstream_id.", file=sys.stderr)
        return 1

    destination_raw = args.local_dir or card.get("storage_path") or ""
    if not str(destination_raw):
        print(f"Model card `{args.card_id}` has no storage_path.", file=sys.stderr)
        return 1

    token = os.environ.get("HF_TOKEN") or None

    print(f"Model card: {args.card_id}")
    print(f"Repository: {repo_id}")
    print(f"Destination: {destination_raw}")
    print(f"Token: {'set' if token else 'not set'}")

    if args.dry_run:
        return 0

    if os.name == "nt" and not args.local_dir and str(destination_raw).startswith("/"):
        print(
            "The model card storage_path is a Linux path. On Windows, pass --local-dir "
            "or run this script on the GPU/Linux host where /models exists.",
            file=sys.stderr,
        )
        return 1

    destination = Path(destination_raw)
    destination.mkdir(parents=True, exist_ok=True)
    downloaded_path = snapshot_download(
        repo_id=repo_id,
        local_dir=destination,
        token=token,
        allow_patterns=args.allow_patterns,
        ignore_patterns=args.ignore_patterns,
    )
    print(f"Downloaded to: {downloaded_path}")
    return 0


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