mod backend_client;
mod error;
mod handlers;
mod protocol;
mod registry;
mod transport_sse;
mod transport_stdio;

use std::sync::Arc;

use backend_client::BackendClient;
use clap::Parser;
pub use error::Result;
use handlers::RequestHandler;
use registry::ToolRegistry;

#[derive(Parser)]
#[command(name = "vapora-mcp-server")]
#[command(about = "VAPORA MCP Server - Real MCP protocol implementation")]
struct Args {
    #[arg(long, default_value = "sse")]
    transport: String,

    #[arg(long, default_value = "127.0.0.1")]
    host: String,

    #[arg(long, default_value = "3000")]
    port: u16,

    #[arg(long, default_value = "http://localhost:8001")]
    backend_url: String,

    #[arg(long)]
    auth_token: Option<String>,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt()
        .with_target(false)
        .compact()
        .init();

    let args = Args::parse();

    tracing::info!(
        "Starting VAPORA MCP Server v{} on {}:{} (transport: {})",
        env!("CARGO_PKG_VERSION"),
        args.host,
        args.port,
        args.transport
    );

    let backend = Arc::new(BackendClient::new(args.backend_url, args.auth_token));
    let registry = Arc::new(ToolRegistry::new());
    let handler = Arc::new(RequestHandler::new(backend, registry));

    match args.transport.as_str() {
        "stdio" => {
            tracing::info!("Running in stdio mode (newline-delimited JSON)");
            let transport = transport_stdio::StdioTransport::new(handler);
            transport.start().await?;
        }
        "sse" => {
            tracing::info!("Running in SSE mode on {}:{}", args.host, args.port);
            let transport = transport_sse::SseTransport::new(args.host, args.port, handler);
            transport.bind().await?;
        }
        mode => {
            anyhow::bail!("Unknown transport mode: {}. Use 'stdio' or 'sse'", mode);
        }
    }

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_args_defaults() {
        let args = Args::try_parse_from(["vapora-mcp-server"]).unwrap();
        assert_eq!(args.transport, "sse");
        assert_eq!(args.host, "127.0.0.1");
        assert_eq!(args.port, 3000);
    }
}
