use std::collections::HashMap;
use std::time::Duration;

use fabro_mcp::client::McpClient;
use fabro_mcp::config::{McpServerSettings, McpTransport};
use fabro_mcp::connection_manager::{McpConnectionManager, call_result_to_string};

fn test_server_config() -> McpServerSettings {
    let test_server = format!("{}/tests/test_mcp_server.py", env!("CARGO_MANIFEST_DIR"));
    McpServerSettings {
        name:                 "test-echo".into(),
        transport:            McpTransport::Stdio {
            command: vec!["python3".into(), test_server],
            env:     HashMap::new(),
        },
        startup_timeout_secs: 10,
        tool_timeout_secs:    30,
    }
}

#[tokio::test]
async fn stdio_client_initialize_and_list_tools() {
    let config = test_server_config();
    let client = McpClient::new(&config).unwrap();
    client.initialize(config.startup_timeout()).await.unwrap();

    let tools = client.list_tools().await.unwrap();
    assert_eq!(tools.len(), 1);
    assert_eq!(tools[0].0, "echo");
    assert_eq!(tools[0].1, "Echo back the message");
}

#[tokio::test]
async fn stdio_client_call_tool_echo() {
    let config = test_server_config();
    let client = McpClient::new(&config).unwrap();
    client.initialize(config.startup_timeout()).await.unwrap();

    let result = client
        .call_tool(
            "echo",
            serde_json::json!({"message": "hello from rust"}),
            Duration::from_secs(10),
        )
        .await
        .unwrap();

    let text = call_result_to_string(&result).unwrap();
    assert_eq!(text, "hello from rust");
}

#[tokio::test]
async fn connection_manager_stdio_roundtrip() {
    let config = test_server_config();
    let mut mgr = McpConnectionManager::new();
    let results = mgr.start_servers(&[config]).await;

    assert_eq!(results.len(), 1);
    let (name, tool_count) = &results[0];
    assert_eq!(name, "test-echo");
    assert_eq!(*tool_count.as_ref().unwrap(), 1);

    let tools = mgr.all_tools();
    assert!(tools.contains_key("mcp__test_echo__echo"));

    let result = mgr
        .call_tool(
            "mcp__test_echo__echo",
            serde_json::json!({"message": "roundtrip"}),
            Duration::from_secs(10),
        )
        .await
        .unwrap();

    let text = call_result_to_string(&result).unwrap();
    assert_eq!(text, "roundtrip");
}
