"""CLI commands for restarting installed products."""
from __future__ import annotations

import click

from k4s.cli.errors import exit_with_error
from k4s.cli.state import CliState
from k4s.cli.target import resolve_target
from k4s.cli.verbosity import apply_command_ui_overrides
from k4s.core.executor import Executor
from k4s.core.products import Step, run_steps
from k4s.recipes.common.run import run


class OrderedRestartGroup(click.Group):
    _order = ["dataiku"]

    def list_commands(self, ctx):
        return self._order


@click.group(cls=OrderedRestartGroup)
def restart():
    """Restart installed products."""
    pass


@restart.command("dataiku")
@click.option(
    "--node-type",
    type=click.Choice(["design", "automation", "govern"], case_sensitive=False),
    metavar="TYPE",
    default="design",
    show_default=True,
    help="DSS node type to restart (design|automation|govern).",
)
@click.option("--os-user", default="dataiku", show_default=True, help="OS user that owns the DSS installation.")
@click.option("--data-dir", default="/data/dataiku/DATA_DIR", show_default=True, help="Dataiku DSS data directory.")
@click.option("--context", "context_name", default=None, help="Context name (or 'local'). Uses current context if omitted.")
@click.option("--dry-run", is_flag=True, help="Print the plan without applying changes.")
@click.option("-q", "--quiet", is_flag=True, help="Only print final results and errors.")
@click.option("-v", "--verbose", count=True, help="Increase verbosity (-v logs, -vv debug).")
@click.pass_context
def dataiku(ctx, node_type, os_user, data_dir, context_name, dry_run, quiet, verbose):
    """Restart a Dataiku DSS node via its systemd service.

    Stops the service, waits briefly, then starts it again.
    The data directory is used only for a quick liveness check before restarting.

    \b
    Examples:
      k4s restart dataiku                              # restarts the design node
      k4s restart dataiku --node-type automation
      k4s restart dataiku --node-type govern --context prod-vm
    """
    state: CliState = ctx.obj["state"]
    apply_command_ui_overrides(ctx, state, quiet=quiet, verbose=verbose)
    ui = state.ui

    try:
        c = resolve_target(state, context_name)
        node_type = node_type.lower()
        svc = f"dataiku.{node_type}"
        data_dir = data_dir.rstrip("/")
        ex = Executor(c.to_server_config())

        def _preflight():
            ui.log(f"Checking that DSS is installed at {data_dir}.")
            rc, _, _ = run(ex, f"test -x {data_dir}/bin/dss", silent=True)
            if rc != 0:
                raise RuntimeError(
                    f"DSS binary not found at '{data_dir}/bin/dss'. "
                    "Check --data-dir or verify the installation."
                )
            ui.log(f"Service: {svc}")

        def _restart():
            ui.log(f"Restarting {svc}.")
            rc, _, err = ex.execute(f"sudo -n systemctl restart {svc}")
            if rc != 0:
                raise RuntimeError(
                    f"Failed to restart {svc}: {err}\n"
                    f"  Check logs with: journalctl -xeu {svc}.service"
                )
            ui.log("Waiting for DSS to become ready.")
            run(ex, "sleep 10", silent=True)

        def _verify():
            ui.log("Verifying service is active.")
            rc, out, _ = ex.execute(f"sudo -n systemctl is-active {svc}")
            if rc != 0 or (out or "").strip() != "active":
                raise RuntimeError(
                    f"{svc} is not active after restart. "
                    f"Check logs with: journalctl -xeu {svc}.service"
                )
            ui.log(f"{svc} is active.")

        steps: list[Step] = [
            Step(title=f"Preflight on {c.host or 'local'}", run=_preflight),
            Step(title=f"Restart {svc}", run=_restart),
            Step(title="Verify service is active", run=_verify),
        ]

        if dry_run:
            run_steps(ui, steps, dry_run=True)
        else:
            with ex:
                run_steps(ui, steps, dry_run=False)
            state.history.append(
                action="restart",
                product="dataiku",
                context=c.name,
                host=c.host,
                params={"node_type": node_type, "service": svc},
            )
            ui.success(f"Dataiku {node_type} node restarted successfully.")

    except Exception as e:
        exit_with_error(ctx, ui, e, code=1)
