"""Discover one ready Catalog and print the immutable version to pin.

Authenticate first with ``hla-compass auth login --env <environment>``.
"""

from __future__ import annotations

import argparse
import json
from collections.abc import Sequence
from typing import Any, Protocol
from uuid import UUID


class CatalogDiscoveryClient(Protocol):
    """Small client surface used by this executable quickstart."""

    def list_catalogs(self) -> list[dict[str, Any]]: ...


def select_ready_catalog(
    client: CatalogDiscoveryClient,
    *,
    provider_key: str,
    catalog_key: str,
) -> dict[str, str]:
    """Return the exact provider, catalog, and ready Catalog Version to use."""

    matches = [
        catalog
        for catalog in client.list_catalogs()
        if catalog.get("providerKey") == provider_key
        and catalog.get("catalogKey") == catalog_key
    ]
    if not matches:
        raise RuntimeError(
            f"Catalog {provider_key}/{catalog_key} is not visible to this organization"
        )
    if len(matches) != 1:
        raise RuntimeError(
            f"Catalog identity {provider_key}/{catalog_key} is ambiguous"
        )

    catalog = matches[0]
    if catalog.get("active") is not True:
        raise RuntimeError(f"Catalog {provider_key}/{catalog_key} is not active")
    current_version = catalog.get("currentVersion")
    if not isinstance(current_version, dict) or not current_version.get("id"):
        raise RuntimeError(
            f"Catalog {provider_key}/{catalog_key} has no ready current version"
        )

    # The discovery API joins only ready versions. Older or other discovery
    # producers may also return an explicit lifecycle field: never ignore it.
    if current_version.get("lifecycleStatus", "ready") != "ready":
        raise RuntimeError(f"Catalog {provider_key}/{catalog_key} is not ready")
    try:
        catalog_id = str(UUID(str(catalog["id"])))
        version_id = str(UUID(str(current_version["id"])))
    except (KeyError, ValueError, TypeError, AttributeError) as exc:
        raise RuntimeError(
            "Discovery returned an invalid Catalog or Version UUID"
        ) from exc

    return {
        "catalogId": catalog_id,
        "providerKey": provider_key,
        "catalogKey": catalog_key,
        "catalogVersionId": version_id,
    }


def main(
    argv: Sequence[str] | None = None,
    *,
    client: CatalogDiscoveryClient | None = None,
) -> int:
    parser = argparse.ArgumentParser(
        description="Discover and pin one ready HLA-Compass Catalog Version."
    )
    parser.add_argument("provider_key")
    parser.add_argument("catalog_key")
    parser.add_argument(
        "--env",
        choices=("dev", "staging", "prod"),
        default="dev",
        help="Authenticated HLA-Compass environment (default: dev).",
    )
    args = parser.parse_args(argv)

    if client is None:
        from hla_compass.client import APIClient

        client = APIClient(environment=args.env)

    try:
        selected = select_ready_catalog(
            client,
            provider_key=args.provider_key,
            catalog_key=args.catalog_key,
        )
    except RuntimeError as exc:
        parser.error(str(exc))
    print(json.dumps(selected, indent=2, sort_keys=True))
    return 0


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