from importlib.metadata import version
from typing import Optional

import typer
from typer import Typer

from harbor.cli.add import add_command
from harbor.cli.adapters import adapters_app
from harbor.cli.admin.admin import admin_app
from harbor.cli.auth import auth_app
from harbor.cli.cache import cache_app
from harbor.cli.datasets import datasets_app
from harbor.cli.download import download_command
from harbor.cli.init import init_command
from harbor.cli.jobs import jobs_app, start
from harbor.cli.sweeps import sweeps_app
from harbor.cli.tasks import tasks_app
from harbor.cli.traces import traces_app
from harbor.cli.trials import trials_app
from harbor.cli.publish import publish_command
from harbor.cli.remove import remove_command
from harbor.cli.sync import sync_command
from harbor.cli.view import view_command


def version_callback(value: bool) -> None:
    if value:
        print(version("harbor"))
        raise typer.Exit()


app = Typer(no_args_is_help=True)


@app.callback()
def main(
    version: Optional[bool] = typer.Option(
        None, "--version", "-v", callback=version_callback, is_eager=True
    ),
) -> None:
    pass


# Primary commands (singular)
app.add_typer(adapters_app, name="adapter", help="Manage adapters.")
app.add_typer(tasks_app, name="task", help="Manage tasks.")
app.add_typer(datasets_app, name="dataset", help="Manage datasets.")
app.add_typer(jobs_app, name="job", help="Manage jobs.")
app.add_typer(trials_app, name="trial", help="Manage trials.")
app.add_typer(cache_app, name="cache", help="Manage Harbor cache.")
app.add_typer(auth_app, name="auth", help="Manage authentication.")

# Plural aliases (hidden, backwards compat)
app.add_typer(adapters_app, name="adapters", help="Manage adapters.", hidden=True)
app.add_typer(tasks_app, name="tasks", help="Manage tasks.", hidden=True)
app.add_typer(datasets_app, name="datasets", help="Manage datasets.", hidden=True)
app.add_typer(jobs_app, name="jobs", help="Manage jobs.", hidden=True)
app.add_typer(trials_app, name="trials", help="Manage trials.", hidden=True)

# Hidden commands (plural only)
app.add_typer(traces_app, name="traces", help="Trace export utilities.", hidden=True)
app.add_typer(
    sweeps_app,
    name="sweeps",
    help="Run successive sweeps to focus on successes.",
    hidden=True,
)
app.add_typer(admin_app, name="admin")

app.command(name="init", help="Initialize a new task or dataset.")(init_command)
app.command(name="run", help="Start a job. Alias for `harbor jobs start`.")(start)
app.command(name="publish", help="Publish tasks and datasets to the Harbor registry.")(
    publish_command
)
app.command(name="add", help="Add tasks or datasets to a dataset.toml.")(add_command)
app.command(name="download", help="Download a task or dataset.")(download_command)
app.command(name="remove", help="Remove tasks from a dataset.toml.")(remove_command)
app.command(name="sync", help="Update task digests in a dataset manifest.")(
    sync_command
)
app.command(name="view", help="Start web server to browse trajectory files.")(
    view_command
)

if __name__ == "__main__":
    app()
