"""ptc infra start — deploy cluster services via Helm."""

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_cluster_record,
    ensure_traefik,
    get_cluster_auth,
    get_cluster_credentials,
)


@cli.subcommand(
    "infra",
    "start",
    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.",
    ),
    offline=Arg(
        "--offline",
        help="Path to a credentials JSON file. Deploys without connecting to PAM.",
    ),
)
def start(
    src: Union[Path, str] = ".",
    config_path: Optional[Path] = None,
    config_key: Optional[str] = None,
    offline: Optional[Path] = None,
) -> None:
    """Start a cluster on infrastructure configured under your own cloud account."""
    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"
    get_cluster_credentials(
        config.deployment.gcp.project, config.deployment.gcp.zone, cluster_name
    )
    public_key = ensure_broker_keypair(config.deployment.infra_secret_name)
    if offline is not None:
        from prodigy_teams_pam_sdk.models import BrokerCredentials, Image, Secrets

        creds_data = srsly.read_json(offline)
        assert isinstance(creds_data, dict)
        creds = BrokerCredentials(
            broker_id=creds_data.get("broker_id", ""),
            public_key=public_key,
            image=Image(
                registry=creds_data.get("container_registry", ""),
                broker_version=creds_data.get("target_broker_version", ""),
                cpl_version=creds_data.get("target_cpl_version", ""),
            ),
            secrets=Secrets(
                container_sa_key=creds_data.get("container_sa_key", ""),
                prodigy_license_key=creds_data.get("prodigy_license_key", ""),
            ),
        )
        values = build_values(config, creds)
    else:
        auth = get_auth_state()
        ensure_cluster_record(
            auth.client,
            auth.org_id,
            config.deployment.domain,
            public_key,
        )
        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()
    upgrade(src / "k8s" / "chart", values=values)
