"""ptc infra provision — provision NFS wheelhouse on a cluster."""

from pathlib import Path
from typing import Optional, Union

import srsly
from radicli import Arg
from wasabi import msg

from ...cli import cli
from ...cluster_config import ClusterConfig
from ...helm import build_values, preflight_test, upgrade
from ._helpers import (
    ensure_broker_keypair,
    ensure_cert_manager,
    ensure_traefik,
    get_cluster_auth,
    get_cluster_credentials,
)


@cli.subcommand(
    "infra",
    "provision",
    src=Arg(help="Path to cluster definition files"),
    config_path=Arg(help="Path to config yaml"),
    config_key=Arg(
        "--config-key",
        help="Top-level key for the cluster config.",
    ),
)
def provision(
    src: Union[Path, str] = ".",
    config_path: Optional[Path] = None,
    config_key: Optional[str] = None,
) -> None:
    """Provision NFS wheelhouse on a cluster (runs provision hook)."""
    from .._state import get_auth_state

    if src == ".":
        src = Path.cwd()
    elif isinstance(src, str):
        src = Path(src)
    if config_path is None:
        config_path = src / "config.yaml"
    config_dict = srsly.read_yaml(config_path)
    assert isinstance(config_dict, dict)
    if config_key is not None:
        config_dict = config_dict[config_key]
    config = ClusterConfig(**config_dict)
    cluster_name = config.deployment.cluster_name
    assert cluster_name, "cluster_name must be set in deployment config"
    auth = get_auth_state()
    get_cluster_credentials(
        config.deployment.gcp.project, config.deployment.gcp.zone, cluster_name
    )
    ensure_broker_keypair(config.deployment.infra_secret_name)
    cluster_auth = get_cluster_auth(auth.client, config.deployment.domain)
    values = build_values(config, cluster_auth)
    msg.info("Running preflight checks...")
    if not preflight_test():
        msg.fail(
            "Preflight checks failed — fix infrastructure issues before deploying."
        )
        raise SystemExit(1)
    ensure_traefik(public_ip=config.deployment.public_ip)
    if config.deployment.acme_email:
        ensure_cert_manager()
    msg.info("Running helm upgrade (provision hook will execute)...")
    upgrade(src / "k8s" / "chart", values=values, wait=True)
