from __future__ import annotations

import typer

from hytop import __version__
from hytop.core.validators import parse_csv_strings, parse_positive_float
from hytop.cpu.cli import app as cpu_app
from hytop.gpu.cli import app as gpu_app
from hytop.net.cli import app as net_app

app = typer.Typer(
    help="hytop toolkit command line",
    context_settings={"help_option_names": ["-h", "--help"]},
)
app.add_typer(gpu_app, name="gpu")
app.add_typer(cpu_app, name="cpu")
app.add_typer(net_app, name="net")


def version_callback(value: bool) -> None:
    """Handle Typer eager version option."""
    if value:
        typer.echo(__version__)
        raise typer.Exit()


@app.callback(invoke_without_command=True)
def root(
    ctx: typer.Context,
    version: bool = typer.Option(
        False,
        "--version",
        "-v",
        callback=version_callback,
        is_eager=True,
        help="Show version and exit.",
    ),
    hosts: str = typer.Option(
        "localhost",
        "--hosts",
        "-H",
        help="Comma-separated hosts, e.g. node01,node02.",
    ),
    interval: float = typer.Option(
        1.0,
        "--interval",
        "-n",
        help="Polling interval in seconds.",
    ),
    window: float = typer.Option(
        5.0,
        "--window",
        help="Single rolling window in seconds.",
    ),
    timeout: float | None = typer.Option(
        None,
        "--timeout",
        help="Max runtime in seconds.",
    ),
) -> None:
    """Root callback that parses global options and stores them in context."""
    if ctx.invoked_subcommand is None:
        typer.echo(ctx.get_help())
        raise typer.Exit()

    try:
        host_list = parse_csv_strings(hosts, "--hosts")
        window_value = parse_positive_float(str(window), "--window")
        timeout_value = float(timeout) if timeout is not None else None
    except ValueError as exc:
        typer.echo(f"argument error: {exc}", err=True)
        raise typer.Exit(code=2) from exc

    ctx.obj = {
        "hosts": host_list,
        "interval": interval,
        "window": window_value,
        "timeout": timeout_value,
    }


def main() -> None:
    app()


if __name__ == "__main__":
    main()
