"""{{ display_name }} MCP server — generated by mcpify. Do not hand-edit.

Terminal Client entry point (`search`/`get`/`call`/`test-connection`/
`config`/`version` run as direct CLI subcommands) and Harness Server entry
point (`start`/`http` boot the persistent MCP server loop) in one Typer
app.
"""

from __future__ import annotations

import asyncio
import os
from typing import Optional

import typer

from ..auth.auth_manager import AuthManager, header_location_for
{%- if "oauth1" in auth_method_keys %}
from ..core.config import AuthMethod, Transport, load_config
{%- else %}
from ..core.config import Transport, load_config
{%- endif %}
from ..core.health_check import ComponentRegistry, HealthCheckManager
from ..core.logger import get_logger, init_logging
from ..core.mcp_server import build_server
from ..core.tracing import build_tracer_provider, shutdown_tracing
from ..data.store import close_cached_connections, open_store, resolve_store_path
from ..http.server import build_http_app, start_http_server
from ..http.types import HttpServerConfig
from . import call as cli_call
from . import config as cli_config
from . import get as cli_get
from . import search as cli_search
from . import setup as cli_setup
from . import test_connection as cli_test_connection
from . import version as cli_version
from . import versions as cli_versions

app = typer.Typer(name="{{ project_name }}", help="{{ display_name }} MCP server")

log = get_logger(__name__)


@app.command()
def setup() -> None:
    """Interactively configure {{ display_name }} credentials and connection settings."""
    asyncio.run(cli_setup.run())


@app.command()
def search(query: str, limit: int = typer.Option(5, "--limit", "-l")) -> None:
    """Semantic search for operations matching a natural-language query."""
    asyncio.run(cli_search.run(query, limit))


@app.command()
def get(operation_id: str) -> None:
    """Show the schema, path, method, and documentation for one operation."""
    asyncio.run(cli_get.run(operation_id))


@app.command()
def call(operation_id: str, args: str = typer.Option("{}", "--args", "-a")) -> None:
    """Validate arguments, invoke the live API, and validate the response."""
    asyncio.run(cli_call.run(operation_id, args))


@app.command()
def start() -> None:
    """Start the Harness Server over stdio (for agent hosts)."""
    os.environ["{{ tool_prefix_env }}_TRANSPORT"] = "stdio"
    asyncio.run(_run_harness_server())


@app.command(name="http")
def http_command(
    host: Optional[str] = typer.Option(None, "--host"),
    port: Optional[int] = typer.Option(None, "--port"),
    cors_allow: Optional[str] = typer.Option(None, "--cors-allow"),
) -> None:
    """Start the Harness Server over HTTP (for agent hosts)."""
    os.environ["{{ tool_prefix_env }}_TRANSPORT"] = "http"
    if host:
        os.environ["{{ tool_prefix_env }}_HOST"] = host
    if port:
        os.environ["{{ tool_prefix_env }}_PORT"] = str(port)
    if cors_allow:
        os.environ["{{ tool_prefix_env }}_CORS_ALLOW"] = cors_allow
    asyncio.run(_run_harness_server())


@app.command(name="test-connection")
def test_connection() -> None:
    """Verify the configured API URL and credentials are reachable."""
    asyncio.run(cli_test_connection.run())


@app.command()
def config() -> None:
    """Print the resolved configuration (secrets redacted)."""
    cli_config.run()


@app.command()
def version() -> None:
    """Print the installed version."""
    cli_version.run()


@app.command()
def versions() -> None:
    """List the API spec versions available in this project."""
    cli_versions.run()


async def _run_harness_server() -> None:
    """Bootstrap order (architecture.md's Runtime Target Architecture):
    config -> logger -> tracing -> registry -> db -> auth -> McpServer ->
    pick transport -> health checks.
    """
    init_logging()
    config_value = load_config()

    {%- if "oauth1" in auth_method_keys %}
    if config_value.transport is Transport.HTTP and config_value.auth_method is AuthMethod.OAUTH1:
        raise RuntimeError(
            "OAuth1 is not supported over HTTP transport: its signature must be "
            "recomputed per request against the destination URL using the server's "
            "consumer key/secret, which a simple incoming-header relay cannot "
            "provide. Use stdio transport for OAuth1-authenticated APIs, or switch "
            "auth_method."
        )
    {%- endif %}

    try:
        tracer_provider = build_tracer_provider("{{ project_name }}")
    except Exception as err:  # telemetry backend unreachable must not crash the server
        log.warning("failed to initialize tracing", error=str(err))
        tracer_provider = None

    db_path = resolve_store_path(config_value.api_version)
    registry = ComponentRegistry()
    health_checks = HealthCheckManager(registry)

    async def check_store() -> None:
        async with open_store(db_path):
            pass

    health_checks.register("store", True, check_store)
    health_task = asyncio.create_task(health_checks.start())

    auth_manager = AuthManager(config_value.auth_method)
    mcp = build_server(config_value.api_version, config_value, auth_manager)

    try:
        if config_value.transport is Transport.HTTP:
            header_location, header_name = header_location_for(config_value.auth_method)
            app_instance = build_http_app(
                mcp, registry, config_value.cors_allow, header_location, header_name
            )
            http_config = HttpServerConfig(
                host=config_value.host, port=config_value.port, cors_allow=config_value.cors_allow
            )
            await start_http_server(app_instance, http_config)
        else:
            await mcp.run_stdio_async()
    finally:
        health_task.cancel()
        await close_cached_connections()
        if tracer_provider is not None:
            shutdown_tracing(tracer_provider)


def main() -> None:
    app()
