"""`acdc ec2` — manage the long-job EC2 instance (up / down / status)."""
from __future__ import annotations

import typer

from acdc_aws_etl_pipeline import config
from acdc_aws_etl_pipeline.cli._internal import runner
from acdc_aws_etl_pipeline.cli._internal.resolve import env_of, load_cfg
from acdc_aws_etl_pipeline.upload.metadata_submitter import create_boto3_session

app = typer.Typer(no_args_is_help=True, help="Manage the long-job EC2 instance.")


def _ec2_env(cfg: dict, env: str) -> config.EnvConfig:
    """Resolve the ``*_ec2`` env that carries the instance id."""
    return env_of(cfg, f"{config.env_base(env)}_ec2")


def _auth_env(cfg: dict, env: str) -> config.EnvConfig:
    """Resolve the non-ec2 env that carries the laptop AWS profile."""
    return env_of(cfg, config.env_base(env))


def _require_instance(e: config.EnvConfig) -> str:
    if not e.ec2_instance_id:
        typer.secho(
            f"No 'ec2_instance_id' configured for env '{e.name}'.",
            fg=typer.colors.RED,
            err=True,
        )
        raise typer.Exit(2)
    return e.ec2_instance_id


def _client(auth: config.EnvConfig):
    session = create_boto3_session(aws_profile=auth.aws_profile, aws_region=auth.region)
    return session.client("ec2")


@app.command()
def up(
    env: str = typer.Option(..., "--env", "-e", help="Environment profile."),
    key: str = typer.Option(None, "--key", help="Path to the .pem SSH key."),
) -> None:
    """Start + bootstrap the EC2 instance (wraps spin_up_ec2.sh)."""
    cfg = load_cfg()
    ec2 = _ec2_env(cfg, env)
    instance_id = _require_instance(ec2)
    ssh_key = key or ec2.ssh_key
    if not ssh_key:
        typer.secho(
            "An SSH key is required: pass --key or set ssh_key in config.",
            fg=typer.colors.RED,
            err=True,
        )
        raise typer.Exit(2)
    runner.run(
        runner.bash_script(
            "infrastructure/ec2/spin_up_ec2.sh",
            "--instance-id", instance_id,
            "--key", ssh_key,
        )
    )


@app.command()
def down(
    env: str = typer.Option(..., "--env", "-e", help="Environment profile."),
) -> None:
    """Stop the EC2 instance."""
    cfg = load_cfg()
    instance_id = _require_instance(_ec2_env(cfg, env))
    client = _client(_auth_env(cfg, env))
    client.stop_instances(InstanceIds=[instance_id])
    typer.secho(f"Stop requested for {instance_id}.", fg=typer.colors.GREEN)


@app.command()
def status(
    env: str = typer.Option(..., "--env", "-e", help="Environment profile."),
) -> None:
    """Show the EC2 instance state and public DNS."""
    cfg = load_cfg()
    instance_id = _require_instance(_ec2_env(cfg, env))
    client = _client(_auth_env(cfg, env))
    resp = client.describe_instances(InstanceIds=[instance_id])
    for res in resp.get("Reservations", []):
        for inst in res.get("Instances", []):
            state = inst.get("State", {}).get("Name", "unknown")
            dns = inst.get("PublicDnsName", "")
            typer.echo(f"{instance_id}: {state} {dns}".rstrip())
