"""anspar-wf CLI - Development toolchain for requirement-traceable projects."""

from __future__ import annotations

import sys
from pathlib import Path

import click

from anspar_wf import __version__

# Package directory (where this file lives after install)
_PKG_DIR = Path(__file__).resolve().parent


def _find_versions_lock() -> Path:
    """Find versions.lock bundled with the package."""
    bundled = _PKG_DIR / "versions.lock"
    if bundled.exists():
        return bundled
    raise click.ClickException(
        "versions.lock not found. Reinstall the package: pip install anspar-wf"
    )


def _find_plugins_dir() -> Path:
    """Find the plugins directory shipped with the package.

    For editable installs: src/anspar_wf/../../plugins
    For regular installs: check sibling to site-packages install
    """
    # Walk up from package dir looking for plugins/
    candidate = _PKG_DIR
    for _ in range(5):
        candidate = candidate.parent
        plugins = candidate / "plugins"
        if (plugins / ".claude-plugin").exists():
            return plugins
    raise click.ClickException(
        "Plugins directory not found. "
        "Use --plugins-dir to specify, or reinstall from the repo."
    )


@click.group()
@click.version_option(version=__version__)
def main() -> None:
    """anspar-wf - Development toolchain for requirement-traceable projects."""


# ---------------------------------------------------------------------------
# install: Install/update external tools from versions.lock
# ---------------------------------------------------------------------------
@main.command()
@click.option("--dry-run", is_flag=True, help="Show what would be installed without doing it.")
def install(dry_run: bool) -> None:
    """Install or update external dev tools at pinned versions."""
    from anspar_wf.tools.install_tools import install_all_tools

    versions_lock = _find_versions_lock()
    install_all_tools(versions_lock, dry_run=dry_run)


# ---------------------------------------------------------------------------
# check: Verify tool versions match versions.lock
# ---------------------------------------------------------------------------
@main.command()
@click.option(
    "--versions-env",
    type=click.Path(exists=True, path_type=Path),
    help="Path to a project's .github/versions.env to compare against.",
)
def check(versions_env: Path | None) -> None:
    """Check installed tool versions against versions.lock."""
    from anspar_wf.tools.version_check import check_versions

    versions_lock = _find_versions_lock()
    ok = check_versions(versions_lock, versions_env)
    if not ok:
        sys.exit(1)


# ---------------------------------------------------------------------------
# hooks: Set up git hooks for a project
# ---------------------------------------------------------------------------
@main.command()
@click.option(
    "--project-dir",
    type=click.Path(exists=True, file_okay=False, path_type=Path),
    default=".",
    help="Path to the project repository.",
)
def hooks(project_dir: Path) -> None:
    """Configure git hooks for a project."""
    from anspar_wf.hooks.setup import setup_hooks

    setup_hooks(project_dir)


# ---------------------------------------------------------------------------
# plugins: Manage Claude Code plugin marketplace registration
# ---------------------------------------------------------------------------
@main.group()
def plugins() -> None:
    """Manage Claude Code plugins (optional)."""


@plugins.command()
@click.option(
    "--project-dir",
    type=click.Path(exists=True, file_okay=False, path_type=Path),
    default=".",
    help="Path to the project repository.",
)
@click.option(
    "--plugins-dir",
    type=click.Path(exists=True, file_okay=False, path_type=Path),
    default=None,
    help="Path to plugins directory (auto-detected if omitted).",
)
def register(project_dir: Path, plugins_dir: Path | None) -> None:
    """Register the anspar-wf plugin marketplace in a project's .claude/settings.json."""
    import json

    if plugins_dir is None:
        plugins_dir = _find_plugins_dir()

    settings_path = project_dir / ".claude" / "settings.json"
    if not settings_path.exists():
        raise click.ClickException(f"No .claude/settings.json at {settings_path}")

    settings = json.loads(settings_path.read_text())
    marketplaces = settings.setdefault("extraKnownMarketplaces", {})
    marketplaces["anspar-cc-plugins"] = {
        "source": {"source": "directory", "path": str(plugins_dir)}
    }
    settings_path.write_text(json.dumps(settings, indent=2) + "\n")
    click.echo(f"Registered plugin marketplace at {plugins_dir}")
    click.echo(f"Updated {settings_path}")


# ---------------------------------------------------------------------------
# validate: Validate requirements via elspais
# ---------------------------------------------------------------------------
@main.command()
@click.argument("path", default=".", type=click.Path(exists=True))
def validate(path: str) -> None:
    """Validate requirement format and references (runs elspais validate)."""
    from anspar_wf.requirements.validate_requirements import main as validate_main

    sys.argv = ["validate_requirements", path]
    validate_main()


# ---------------------------------------------------------------------------
# trace: Run trace_view CLI
# ---------------------------------------------------------------------------
@main.command(context_settings={"ignore_unknown_options": True, "allow_extra_args": True})
@click.pass_context
def trace(ctx: click.Context) -> None:
    """Generate requirement traceability view (passes args to trace_view CLI)."""
    from anspar_wf.requirements.trace_view.cli import main as trace_main

    sys.argv = ["trace-view", *ctx.args]
    trace_main()


# ---------------------------------------------------------------------------
# serve: Serve trace_view HTML
# ---------------------------------------------------------------------------
@main.command()
@click.option("--port", default=8080, help="Port to serve on.")
@click.option("--directory", default=".", help="Directory containing trace output.")
def serve(port: int, directory: str) -> None:
    """Serve the trace_view HTML report via a local HTTP server."""
    import http.server
    import os

    os.chdir(directory)
    click.echo(f"Serving trace view at http://localhost:{port}")
    click.echo("Press Ctrl+C to stop.")
    handler = http.server.SimpleHTTPRequestHandler
    httpd = http.server.HTTPServer(("", port), handler)
    httpd.serve_forever()


# ---------------------------------------------------------------------------
# mcp: Start MCP servers
# ---------------------------------------------------------------------------
@main.group()
def mcp() -> None:
    """Start MCP servers for Claude Code integration."""


@mcp.command()
def traceability() -> None:
    """Start the requirement-traceability MCP server."""
    from anspar_wf.mcp.traceability.server import main as mcp_main

    mcp_main()


@mcp.command()
def compliance() -> None:
    """Start the compliance-verification MCP server."""
    from anspar_wf.mcp.compliance.server import main as mcp_main

    mcp_main()


if __name__ == "__main__":
    main()
