//! Build a starter eval dataset from MCP-native sources.
//!
//! A `tools/list` snapshot or a registry export already describes a server's
//! surface. These helpers turn that surface into starter [`ImportedTask`]s, one
//! per tool or per registry entry, so a developer gets a runnable mcptest suite
//! to edit rather than a blank file.

use serde_json::Value;

use crate::benchmark_import::ImportedTask;

/// Build one starter task per tool in a `tools/list` snapshot.
///
/// Accepts `{ "tools": [...] }`, the raw JSON-RPC `{ "result": { "tools": [] }}`
/// shape, or a bare array. Each task prompts the agent to exercise the tool and
/// records the tool description so the author has context.
pub fn from_tools_list(snapshot: &Value) -> Vec<ImportedTask> {
    let tools = snapshot
        .get("tools")
        .or_else(|| snapshot.pointer("/result/tools"))
        .and_then(Value::as_array)
        .or_else(|| snapshot.as_array())
        .cloned()
        .unwrap_or_default();
    tools.iter().filter_map(tool_to_task).collect()
}

/// Map one tool entry to a starter task.
fn tool_to_task(tool: &Value) -> Option<ImportedTask> {
    let name = tool.get("name").and_then(Value::as_str)?.trim().to_string();
    if name.is_empty() {
        return None;
    }
    let description = tool
        .get("description")
        .and_then(Value::as_str)
        .unwrap_or("")
        .trim();
    let prompt = if description.is_empty() {
        format!("Use the `{name}` tool to complete a representative task.")
    } else {
        format!(
            "Use the `{name}` tool to complete a representative task. Tool purpose: {description}"
        )
    };
    Some(ImportedTask {
        name: format!("exercise {name}"),
        prompt,
        expect: None,
    })
}

/// Build one starter task per server in a registry export.
///
/// Accepts `{ "servers": [...] }` or a bare array. Each task prompts the agent
/// to connect to the named server and exercise a primary tool.
pub fn from_registry(export: &Value) -> Vec<ImportedTask> {
    let servers = export
        .get("servers")
        .and_then(Value::as_array)
        .or_else(|| export.as_array())
        .cloned()
        .unwrap_or_default();
    servers.iter().filter_map(registry_entry_to_task).collect()
}

/// Map one registry server entry to a starter task.
fn registry_entry_to_task(entry: &Value) -> Option<ImportedTask> {
    let name = entry
        .get("name")
        .and_then(Value::as_str)?
        .trim()
        .to_string();
    if name.is_empty() {
        return None;
    }
    let description = entry
        .get("description")
        .and_then(Value::as_str)
        .unwrap_or("")
        .trim();
    let context = if description.is_empty() {
        String::new()
    } else {
        format!(" Server purpose: {description}")
    };
    Some(ImportedTask {
        name: format!("smoke {name}"),
        prompt: format!("Connect to the `{name}` MCP server, list its tools, and exercise one of them.{context}"),
        expect: None,
    })
}
