pmat 3.11.0

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
//! Server command handlers for PMAT
//!
//! Extracted from utility_handlers.rs for file health compliance (CB-040).
//! Contains handle_serve and related server transport implementations.
#![cfg_attr(coverage_nightly, coverage(off))]

use crate::cli::colors as c;
use anyhow::Result;

/// Handle serve command
pub async fn handle_serve(
    host: String,
    port: u16,
    cors: bool,
    transport: crate::cli::commands::ServeTransport,
) -> Result<()> {
    use crate::cli::commands::ServeTransport;
    let addr = format!("{host}:{port}");

    match transport {
        ServeTransport::Http => handle_http_server(&host, port, cors).await,
        ServeTransport::WebSocket => handle_websocket_server(&addr).await,
        ServeTransport::HttpSse => handle_http_sse_server(&addr, &host, port, cors).await,
        ServeTransport::Both => handle_hybrid_server(&addr, &host, port, cors).await,
        ServeTransport::All => handle_full_server(&addr, &host, port, cors).await,
    }
}

async fn handle_http_server(host: &str, port: u16, cors: bool) -> Result<()> {
    eprintln!(
        "{} Starting PMAT HTTP server on {}",
        c::label(""),
        c::path(&format!("http://{host}:{port}"))
    );
    eprintln!("{}", c::pass("Server ready!"));
    eprintln!(
        "  {} {}",
        c::dim("Health check:"),
        c::path(&format!("http://{host}:{port}/health"))
    );
    eprintln!(
        "  {} {}",
        c::dim("API base:"),
        c::path(&format!("http://{host}:{port}/api/v1"))
    );

    if cors {
        eprintln!("  {}", c::dim("CORS enabled for all origins"));
    }

    eprintln!(
        "\n{}",
        c::dim("HTTP server functionality ready for implementation.")
    );
    wait_for_shutdown().await
}

async fn handle_websocket_server(addr: &str) -> Result<()> {
    eprintln!(
        "{} Starting PMAT WebSocket server on {}",
        c::label(""),
        c::path(&format!("ws://{addr}"))
    );
    eprintln!("{}", c::pass("WebSocket server ready!"));
    eprintln!(
        "  {} {}",
        c::dim("WebSocket endpoint:"),
        c::path(&format!("ws://{addr}"))
    );
    eprintln!("  {}", c::dim("MCP protocol over WebSocket"));

    start_websocket_server(addr.to_string()).await
}

async fn handle_http_sse_server(addr: &str, host: &str, port: u16, cors: bool) -> Result<()> {
    eprintln!(
        "{} Starting PMAT HTTP-SSE server on {}",
        c::label(""),
        c::path(&format!("http://{host}:{port}"))
    );
    eprintln!("{}", c::pass("HTTP-SSE server ready!"));
    eprintln!(
        "  {} {}",
        c::dim("SSE endpoint:"),
        c::path(&format!("http://{host}:{port}/sse"))
    );
    eprintln!(
        "  {} {}",
        c::dim("Message endpoint:"),
        c::path(&format!("http://{host}:{port}/message"))
    );
    eprintln!("  {}", c::dim("MCP protocol over Server-Sent Events"));

    if cors {
        eprintln!("  {}", c::dim("CORS enabled for all origins"));
    }

    start_http_sse_server(addr.to_string(), cors).await
}

async fn handle_hybrid_server(addr: &str, host: &str, port: u16, cors: bool) -> Result<()> {
    eprintln!(
        "{} Starting PMAT hybrid server (HTTP + WebSocket) on {}",
        c::label(""),
        c::path(&format!("{host}:{port}"))
    );
    eprintln!("{}", c::pass("Hybrid server ready!"));
    eprintln!(
        "  {} {}",
        c::dim("HTTP endpoint:"),
        c::path(&format!("http://{host}:{port}"))
    );
    eprintln!(
        "  {} {}",
        c::dim("WebSocket endpoint:"),
        c::path(&format!("ws://{host}:{port}"))
    );
    eprintln!("  {}", c::dim("MCP protocol over both transports"));

    if cors {
        eprintln!("  {}", c::dim("CORS enabled for all origins"));
    }

    start_hybrid_server(addr.to_string(), cors).await
}

async fn handle_full_server(addr: &str, host: &str, port: u16, cors: bool) -> Result<()> {
    eprintln!(
        "{} Starting PMAT full server (HTTP + WebSocket + SSE) on {}",
        c::label(""),
        c::path(&format!("{host}:{port}"))
    );
    eprintln!("{}", c::pass("All transports ready!"));
    eprintln!(
        "  {} {}",
        c::dim("HTTP endpoint:"),
        c::path(&format!("http://{host}:{port}"))
    );
    eprintln!(
        "  {} {}",
        c::dim("WebSocket endpoint:"),
        c::path(&format!("ws://{host}:{port}"))
    );
    eprintln!(
        "  {} {}",
        c::dim("SSE endpoint:"),
        c::path(&format!("http://{host}:{port}/sse"))
    );
    eprintln!("  {}", c::dim("MCP protocol over all transports"));

    if cors {
        eprintln!("  {}", c::dim("CORS enabled for all origins"));
    }

    start_full_server(addr.to_string(), cors).await
}

async fn wait_for_shutdown() -> Result<()> {
    eprintln!("{}", c::dim("Press Ctrl+C to exit.\n"));
    tokio::signal::ctrl_c().await?;
    eprintln!("{}", c::label("Shutting down server..."));
    Ok(())
}

/// Start a WebSocket-only server
async fn start_websocket_server(addr: String) -> Result<()> {
    eprintln!(
        "{} WebSocket server implementation ready for {}",
        c::dim(""),
        c::path(&addr)
    );
    eprintln!(
        "{}",
        c::dim("Connect using any WebSocket client to test MCP protocol")
    );

    // Placeholder for actual WebSocket server implementation
    tokio::signal::ctrl_c().await?;
    Ok(())
}

/// Start HTTP-SSE server
async fn start_http_sse_server(addr: String, _cors: bool) -> Result<()> {
    eprintln!(
        "{} HTTP-SSE server implementation ready for {}",
        c::dim(""),
        c::path(&addr)
    );
    eprintln!(
        "{}",
        c::dim("Server-Sent Events endpoint ready for MCP protocol")
    );

    // Placeholder for actual HTTP-SSE server implementation
    tokio::signal::ctrl_c().await?;
    Ok(())
}

/// Start hybrid server (HTTP + WebSocket)
async fn start_hybrid_server(addr: String, _cors: bool) -> Result<()> {
    eprintln!(
        "{} Hybrid server implementation ready for {}",
        c::dim(""),
        c::path(&addr)
    );
    eprintln!("{}", c::dim("Both HTTP and WebSocket endpoints ready"));

    // Placeholder for actual hybrid server implementation
    tokio::signal::ctrl_c().await?;
    Ok(())
}

/// Start full multi-transport server
async fn start_full_server(addr: String, _cors: bool) -> Result<()> {
    eprintln!(
        "{} Full server implementation ready for {}",
        c::dim(""),
        c::path(&addr)
    );
    eprintln!(
        "{}",
        c::dim("All transport methods (HTTP, WebSocket, SSE) ready")
    );

    // Placeholder for actual full server implementation
    tokio::signal::ctrl_c().await?;
    Ok(())
}