//! JSON-RPC 2.0 over stdio 协议层
//!
//! 职责:
//! - 按行读 stdin,解析 JSON-RPC Request/Notification
//! - 构造 Response / Error 对象并序列化为单行 JSON 写 stdout
//! - MCP 三类方法路由(initialize / tools/list / tools/call)由上层 dispatch
//!
//! 不解析 batch 请求(MCP 客户端实测逐条发,单条足够)。
//! 错误码遵循 JSON-RPC 2.0 + MCP 自定义段(-32xxx 协议层 / 0xffff 工具层)。

use serde::{Deserialize, Serialize};
use serde_json::Value;

// ============================================================
// JSON-RPC 2.0 错误码
// ============================================================

/// 协议层错误(JSON-RPC 2.0 预留段 -32000..-32099)
pub const PARSE_ERROR: i32 = -32700;
pub const INVALID_REQUEST: i32 = -32600;
pub const METHOD_NOT_FOUND: i32 = -32601;
pub const INVALID_PARAMS: i32 = -32602;
pub const INTERNAL_ERROR: i32 = -32603;

// ============================================================
// 请求 / 响应数据结构
// ============================================================

/// JSON-RPC 2.0 请求(请求与通知共用,Notification 时 id=None)
#[derive(Debug, Clone, Deserialize)]
pub struct Request {
    pub jsonrpc: Option<String>,
    pub id: Option<Value>,
    pub method: String,
    #[serde(default)]
    pub params: Value,
}

/// JSON-RPC 2.0 错误对象
#[derive(Debug, Clone, Serialize)]
pub struct ErrorObject {
    pub code: i32,
    pub message: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data: Option<Value>,
}

/// JSON-RPC 2.0 响应
#[derive(Debug, Clone, Serialize)]
pub struct Response {
    pub jsonrpc: &'static str,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub result: Option<Value>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<ErrorObject>,
}

impl Response {
    /// 成功响应
    pub fn ok(id: Option<Value>, result: Value) -> Self {
        Self {
            jsonrpc: "2.0",
            id,
            result: Some(result),
            error: None,
        }
    }

    /// 错误响应
    pub fn err(id: Option<Value>, code: i32, message: impl Into<String>, data: Option<Value>) -> Self {
        Self {
            jsonrpc: "2.0",
            id,
            result: None,
            error: Some(ErrorObject {
                code,
                message: message.into(),
                data,
            }),
        }
    }
}

// ============================================================
// MCP 方法路由 — 暴露给上层 dispatch 的 enum
// ============================================================

/// MCP 协议层方法(已剥离 JSON-RPC 包装)。未知方法返回 `Unknown`,由 dispatch 回 METHOD_NOT_FOUND。
#[derive(Debug, Clone)]
pub enum McpMethod {
    /// initialize 握手:返 server info + capabilities
    Initialize { params: Value },
    /// initialized 通知:客户端确认握手完成,无需响应
    Initialized,
    /// tools/list:列出所有工具(MCP Tool schema)
    ToolsList,
    /// tools/call:调用某工具
    ToolsCall { name: String, arguments: Value },
    /// ping 心跳(MCP 2025 规范),回空 result
    Ping,
    /// 未识别的方法(回 METHOD_NOT_FOUND)
    Unknown(String),
}

impl McpMethod {
    /// 从 Request 路由出 MCP 语义方法。
    pub fn from_request(req: &Request) -> Self {
        match req.method.as_str() {
            "initialize" => McpMethod::Initialize { params: req.params.clone() },
            "notifications/initialized" => McpMethod::Initialized,
            "tools/list" => McpMethod::ToolsList,
            "tools/call" => {
                let name = req
                    .params
                    .get("name")
                    .and_then(|v| v.as_str())
                    .unwrap_or("")
                    .to_owned();
                let arguments = req.params.get("arguments").cloned().unwrap_or(Value::Null);
                McpMethod::ToolsCall { name, arguments }
            }
            "ping" => McpMethod::Ping,
            other => McpMethod::Unknown(other.to_owned()),
        }
    }
}

// ============================================================
// MCP 协议数据结构(initialize 握手 / Tool schema / CallToolResult)
// ============================================================

/// MCP initialize 握手响应结构(server info + capabilities)
#[derive(Debug, Clone, Serialize)]
pub struct InitializeResult {
    #[serde(rename = "protocolVersion")]
    pub protocol_version: &'static str,
    pub capabilities: Capabilities,
    #[serde(rename = "serverInfo")]
    pub server_info: ServerInfo,
}

#[derive(Debug, Clone, Serialize)]
pub struct Capabilities {
    pub tools: ToolsCapability,
}

#[derive(Debug, Clone, Serialize)]
pub struct ToolsCapability {
    #[serde(rename = "listChanged")]
    pub list_changed: bool,
}

#[derive(Debug, Clone, Serialize)]
pub struct ServerInfo {
    pub name: &'static str,
    pub version: &'static str,
}

/// MCP Tool 描述符(tools/list 返回数组元素)
#[derive(Debug, Clone, Serialize)]
pub struct Tool {
    pub name: &'static str,
    pub description: &'static str,
    #[serde(rename = "inputSchema")]
    pub input_schema: Value,
}

/// MCP tools/call 成功响应(CallToolResult)
#[derive(Debug, Clone, Serialize)]
pub struct CallToolResult {
    pub content: Vec<ContentBlock>,
    #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
    pub is_error: Option<bool>,
}

/// MCP 内容块(本 server 仅用 text)
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum ContentBlock {
    Text { text: String },
}

impl CallToolResult {
    /// 文本成功响应
    pub fn text(text: impl Into<String>) -> Self {
        Self {
            content: vec![ContentBlock::Text { text: text.into() }],
            is_error: None,
        }
    }

    /// 文本错误响应(is_error=true 让客户端区分「工具业务错」与「协议错」)
    pub fn error(text: impl Into<String>) -> Self {
        Self {
            content: vec![ContentBlock::Text { text: text.into() }],
            is_error: Some(true),
        }
    }
}
