from __future__ import annotations

import argparse
import sys
from pathlib import Path

from common import iter_model_card_paths, read_yaml_mapping

REQUIRED_FIELDS = {
    "id",
    "name",
    "type",
    "task",
    "language",
    "source",
    "license",
    "status",
    "storage_path",
    "deployment",
}

VALID_STATUSES = {"candidate", "draft", "staging", "production", "archived"}


def load_yaml(path: Path) -> dict:
    return read_yaml_mapping(path)


def validate_card(path: Path) -> list[str]:
    errors: list[str] = []

    try:
        data = load_yaml(path)
    except Exception as exc:
        return [f"{path}: cannot parse YAML: {exc}"]

    missing = sorted(REQUIRED_FIELDS - set(data))
    for field in missing:
        errors.append(f"{path}: missing required field `{field}`")

    status = data.get("status")
    if status is not None and status not in VALID_STATUSES:
        errors.append(
            f"{path}: invalid status `{status}`, expected one of {sorted(VALID_STATUSES)}"
        )

    for field in ("task", "language"):
        value = data.get(field)
        if value is not None and not isinstance(value, list):
            errors.append(f"{path}: `{field}` must be a list")

    deployment = data.get("deployment")
    if deployment is not None and not isinstance(deployment, dict):
        errors.append(f"{path}: `deployment` must be a mapping")

    return errors


def main() -> int:
    parser = argparse.ArgumentParser(description="Validate model cards.")
    parser.add_argument("--include-examples", action="store_true")
    args = parser.parse_args()

    cards = iter_model_card_paths(include_examples=args.include_examples)
    if not cards:
        print("No model cards found.")
        return 0

    errors: list[str] = []
    for card in cards:
        errors.extend(validate_card(card))

    if errors:
        print("Model card validation failed:")
        for error in errors:
            print(f"- {error}")
        return 1

    print(f"Validated {len(cards)} model card(s).")
    return 0


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