"""hdx validate — run MCP protocol compliance checks against a server."""

from __future__ import annotations

import asyncio
import json

import click

from hatchdx.harness.simulator import SimulatorError
from hatchdx.utils import console
from hatchdx.utils.command import resolve_command
from hatchdx.utils.config import ConfigError, load_config
from hatchdx.validator.models import ValidatorError
from hatchdx.validator.reporter import report_validation, report_validation_json
from hatchdx.validator.runner import run_validation


@click.command("validate")
@click.option(
    "--severity",
    "-s",
    type=click.Choice(["error", "warning", "info"]),
    default=None,
    help="Minimum severity level to display.",
)
@click.option(
    "--category",
    "-c",
    type=click.Choice([
        "naming", "schema", "annotations", "errors", "response", "pagination",
    ]),
    default=None,
    help="Only run rules from this category.",
)
@click.option(
    "--json-output",
    "json_output",
    is_flag=True,
    help="Output machine-readable JSON (for CI pipelines).",
)
@click.option(
    "--verbose",
    "-v",
    is_flag=True,
    help="Show passing rules in addition to failures.",
)
@click.option(
    "--timeout",
    "-t",
    default=5000,
    type=int,
    help="Timeout per operation in milliseconds.",
)
def validate_cmd(severity, category, json_output, verbose, timeout):
    """Run MCP protocol compliance checks against your server."""
    # 1. Load project config.
    try:
        config = load_config()
    except ConfigError as exc:
        console.error(str(exc))
        raise SystemExit(1)

    if not json_output:
        console.info(f"Validating {config.server_name}")
        click.echo()

    # 2. Resolve server command.
    try:
        command = resolve_command(config.server_command)
    except ValueError as exc:
        console.error(f"Invalid server command: {exc}")
        raise SystemExit(1)

    if not command:
        console.error("Server command is empty. Check your hdx config.")
        raise SystemExit(1)

    timeout_sec = timeout / 1000

    if not json_output:
        console.step("Starting server...")

    # 3. Run validation.
    try:
        report = asyncio.run(
            run_validation(
                command,
                server_name=config.server_name,
                timeout=timeout_sec,
                category_filter=category,
                severity_filter=severity,
            )
        )
    except SimulatorError as exc:
        if json_output:
            click.echo(json.dumps({"error": str(exc)}))
        else:
            click.echo()
            console.error(f"Failed to start server: {exc}")
            click.echo()
            click.echo("  Make sure your server is installed:")
            click.echo("    uv sync")
        raise SystemExit(1)
    except ValidatorError as exc:
        if json_output:
            click.echo(json.dumps({"error": str(exc)}))
        else:
            console.error(str(exc))
        raise SystemExit(1)

    if not json_output:
        console.success("Server started")

    # 4. Display results.
    if json_output:
        click.echo(json.dumps(report_validation_json(report), indent=2))
        exit_code = 1 if report.has_errors else 0
    else:
        exit_code = report_validation(
            report,
            verbose=verbose,
            min_severity=severity,
        )

    raise SystemExit(exit_code)
