"""CLI groups for organizing Lightning SDK commands."""

import rich_click as click

from lightning_sdk.cli.api import APIGroup
from lightning_sdk.cli.api import register_commands as register_api_commands
from lightning_sdk.cli.auth import register_commands as register_auth_commands
from lightning_sdk.cli.base_studio import register_commands as register_base_studio_commands
from lightning_sdk.cli.code import register_commands as register_code_commands
from lightning_sdk.cli.config import register_commands as register_config_commands
from lightning_sdk.cli.connection import register_commands as register_connection_commands
from lightning_sdk.cli.container import register_commands as register_container_commands
from lightning_sdk.cli.cp import register_commands as register_cp_commands
from lightning_sdk.cli.cp.completion import complete_cp_path
from lightning_sdk.cli.dataset import register_commands as register_dataset_commands
from lightning_sdk.cli.deployment import register_commands as register_deployment_commands
from lightning_sdk.cli.edit import register_commands as register_edit_commands
from lightning_sdk.cli.file import register_commands as register_file_commands
from lightning_sdk.cli.folder import register_commands as register_folder_commands
from lightning_sdk.cli.job import register_commands as register_job_commands
from lightning_sdk.cli.legacy_redirects import DeprecatedGroup
from lightning_sdk.cli.license import register_commands as register_license_commands
from lightning_sdk.cli.machine import register_commands as register_machine_commands
from lightning_sdk.cli.mmt import register_commands as register_mmt_commands
from lightning_sdk.cli.model import register_commands as register_model_commands
from lightning_sdk.cli.pipeline import register_commands as register_pipeline_commands
from lightning_sdk.cli.sandbox import register_commands as register_sandbox_commands
from lightning_sdk.cli.ssh import register_commands as register_ssh_commands
from lightning_sdk.cli.studio import register_commands as register_studio_commands
from lightning_sdk.cli.teamspace import register_commands as register_teamspace_commands
from lightning_sdk.cli.user import register_commands as register_user_commands
from lightning_sdk.cli.utils.logging import LightningCommand, LightningGroup
from lightning_sdk.cli.vm import register_commands as register_vm_commands


@click.group(name="studio", cls=LightningGroup)
def studio() -> None:
    """Persistent GPU dev workspaces."""


@click.group(name="user", cls=LightningGroup)
def user() -> None:
    """Manage the authenticated user."""


@click.group(name="teamspace", cls=LightningGroup)
def teamspace() -> None:
    """Manage Lightning teamspaces."""


@click.group(name="job", cls=LightningGroup)
def job() -> None:
    """Run batch jobs and sweeps."""


@click.group(name="mmt", cls=DeprecatedGroup, hidden=False, replacement="lightning job", replacement_group=job)
def mmt() -> None:
    """Multi-node distributed training."""


@click.group(name="machine", cls=LightningGroup)
def machine() -> None:
    """Browse GPU and CPU machine types."""


@click.group(name="config", cls=LightningGroup)
def config() -> None:
    """Manage SDK and CLI settings."""


@click.group(
    name="api",
    cls=APIGroup,
    hidden=True,
    invoke_without_command=True,
    no_args_is_help=False,
    context_settings={"ignore_unknown_options": True, "allow_extra_args": True},
)
@click.pass_context
def api(ctx: click.Context) -> None:
    """Manage Lightning AI APIs.

    Use `lightning api /path [options]` to make an authenticated raw HTTP request.
    """
    if ctx.invoked_subcommand is None and not ctx.args:
        click.echo(ctx.get_help())
        ctx.exit()


@click.group(name="deployment", cls=LightningGroup)
def deployment() -> None:
    """Deploy autoscaling inference APIs."""


@click.group(name="vm", cls=LightningGroup)
def vm() -> None:
    """Create and manage virtual machines."""


@click.group(name="sandbox", cls=LightningGroup)
def sandbox() -> None:
    """Ephemeral sandboxes for agents.

    Set LIGHTNING_SANDBOX_API_KEY for non-interactive authentication. The sandbox
    API uses https://platform.lightning.ai by default; set LIGHTNING_CLOUD_URL to override
    the host.

    Examples:
      $ sandbox list --teamspace owner/teamspace --limit 2
      ┏━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
      ┃ ID     ┃ Name   ┃ Status  ┃ Instance type ┃ Persistent ┃
      ┡━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
      │ sbx-42 │ devbox │ running │ cpu-1         │ yes        │
      └────────┴────────┴─────────┴───────────────┴────────────┘

      $ sandbox create --name devbox --teamspace owner/teamspace --persistent
      ┏━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
      ┃ ID     ┃ Name   ┃ Status  ┃ Instance type ┃ Persistent ┃
      ┡━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
      │ sbx-42 │ devbox │ running │ cpu-1         │ yes        │
      └────────┴────────┴─────────┴───────────────┴────────────┘

      $ sandbox run sbx-42 -- python -c "print('hello')"
      hello

      $ sandbox run sbx-42 --detached -- bash -lc "echo start; sleep 1; echo done"
      cmd-abc123

      $ sandbox logs sbx-42 cmd-abc123 --no-timestamps
      start
      done

      $ sandbox stop sbx-42
      Stopped sandbox sbx-42
      Auto snapshot: snap-abc123
    """


@click.group(name="container", cls=LightningGroup)
def container() -> None:
    """Run and manage containers."""


@click.group(name="model", cls=LightningGroup)
def model() -> None:
    """Register and version models."""


@click.group(name="pipeline", cls=LightningGroup)
def pipeline() -> None:
    """Build and manage pipelines."""


@click.group(name="code", cls=LightningGroup)
def code() -> None:
    """Coding agents on code.lightning.ai."""


@click.group(name="auth", cls=LightningGroup)
def auth() -> None:
    """Identity and access: who you are, and what you're allowed to do."""


@click.group(name="file", cls=DeprecatedGroup, replacement="lightning cp")
def file() -> None:
    """Upload and download files."""


@click.group(name="folder", cls=DeprecatedGroup, replacement="lightning cp -r")
def folder() -> None:
    """Upload and download folders."""


@click.group(name="ssh", cls=LightningGroup)
def ssh() -> None:
    """Configure SSH access to Studios."""


@click.group(name="base-studio", cls=LightningGroup)
def base_studio() -> None:
    """Reusable Studio environment images."""


@click.group(name="license", cls=LightningGroup)
def license() -> None:  # noqa: A001
    """View and manage product licenses."""


@click.group(name="dataset", cls=LightningGroup, hidden=True)
def dataset() -> None:
    """Download datasets."""


@click.group(name="connection", cls=LightningGroup)
def connection() -> None:
    """Work with teamspace data connections."""


@click.command(name="cp", cls=LightningCommand)
@click.argument("source", shell_complete=complete_cp_path)
@click.argument("destination", required=False, shell_complete=complete_cp_path)
@click.option("--recursive", "-r", is_flag=True, help="Copy directories recursively")
@click.option(
    "--cloud-account",
    "cloud_account",
    default=None,
    help=(
        "Cloud account to store uploads on. Where one is needed, defaults to the current "
        "cloud account (LIGHTNING_CLUSTER_ID) or the teamspace's default cloud account."
    ),
)
@click.pass_context
def cp(_ctx: click.Context) -> None:
    """Copy between local, Studios, Drive.

    Every lit:// URL must include a resource root at the start of its drive path
    that tells Lightning where to send the file. There is no default - a URL
    without a root will fail.

    URL formats:
      Studios:          lit://<owner>/<teamspace>/studios/<studio-name>/<path>
      Teamspace drives: lit://<owner>/<teamspace>/uploads/<path>
      Current teamspace (relative): lit:///<resource-root>/<path>

    Examples:
      lightning cp source.txt lit://<owner>/<my-teamspace>/studios/<my-studio>/destination.txt
      lightning cp -r source_folder/ lit://<owner>/<my-teamspace>/studios/<my-studio>/destination_folder/
      lightning cp source.txt lit://<owner>/<my-teamspace>/uploads/destination.txt
      lightning cp source.txt lit:///uploads/destination.txt
      lightning cp -r source_folder/ lit:///studios/<my-studio>/destination_folder/
    """


@click.command(name="edit", cls=LightningCommand)
@click.argument("path")
@click.option(
    "--editor",
    default=None,
    help="Editor command to launch. Defaults to the $EDITOR environment variable, or vi.",
)
@click.pass_context
def edit(_ctx: click.Context) -> None:
    """Edit a Drive file in place with a local editor.

    Downloads the file, opens it in your editor, and re-uploads it when you save
    and close, only if the contents changed.

    URL formats:
      Studios:          lit://<owner>/<teamspace>/studios/<studio-name>/<path>
      Teamspace drives: lit://<owner>/<teamspace>/uploads/<path>
      Current teamspace (relative): lit:///<resource-root>/<path>

    Examples:
      lightning edit lit://<owner>/<my-teamspace>/studios/<my-studio>/notes.txt
      lightning edit lit:///studios/<my-studio>/notes.txt
      lightning edit lit://<owner>/<my-teamspace>/uploads/config.yaml --editor "code -w"
    """


# Register config commands with the main config group
register_job_commands(job)
register_mmt_commands(mmt)
register_machine_commands(machine)
register_studio_commands(studio)
register_user_commands(user)
register_teamspace_commands(teamspace)
register_config_commands(config)
register_api_commands(api)
register_deployment_commands(deployment)
register_vm_commands(vm)
register_sandbox_commands(sandbox)
register_container_commands(container)
register_model_commands(model)
register_pipeline_commands(pipeline)
register_auth_commands(auth)
register_code_commands(code)
register_file_commands(file)
register_folder_commands(folder)
register_ssh_commands(ssh)
register_base_studio_commands(base_studio)
register_license_commands(license)
register_dataset_commands(dataset)
register_connection_commands(connection)
register_cp_commands(cp)
register_edit_commands(edit)
