pmat 2.93.1

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP, HTTP)
//! Simplified MCP implementation using uniform contracts
//! This version doesn't depend on pmcp crate

use super::simple_service::SimpleContractService;
use super::{AnalyzeComplexityContract, AnalyzeSatdContract, AnalyzeDeadCodeContract, AnalyzeTdgContract, AnalyzeLintHotspotContract, QualityGateContract, AnalyzeEntropyContract, RefactorAutoContract};
use anyhow::Result;
use serde_json::{json, Value};
use std::sync::Arc;

/// Simplified MCP handler using uniform contracts
pub struct SimpleMcpHandler {
    service: Arc<SimpleContractService>,
}

impl SimpleMcpHandler {
    pub fn new() -> Result<Self> {
        Ok(Self {
            service: Arc::new(SimpleContractService::new()?),
        })
    }

    /// Handle MCP tool call using uniform contracts
    pub async fn handle_tool_call(&self, name: &str, params: Value) -> Result<Value> {
        // Apply backward compatibility mapping
        let params = super::adapter::BackwardCompatibility::map_json_params(params);

        match name {
            "analyze_complexity" => self.handle_analyze_complexity(params).await,
            "analyze_satd" => self.handle_analyze_satd(params).await,
            "analyze_dead_code" => self.handle_analyze_dead_code(params).await,
            "analyze_tdg" => self.handle_analyze_tdg(params).await,
            "analyze_lint_hotspot" => self.handle_analyze_lint_hotspot(params).await,
            "analyze_entropy" => self.handle_analyze_entropy(params).await,
            "quality_gate" => self.handle_quality_gate(params).await,
            "refactor_auto" => self.handle_refactor_auto(params).await,
            _ => Err(anyhow::anyhow!("Unknown tool: {name}")),
        }
    }

    async fn handle_analyze_complexity(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeComplexityContract>(params)?;
        self.service.analyze_complexity(contract).await
    }

    async fn handle_analyze_satd(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeSatdContract>(params)?;
        self.service.analyze_satd(contract).await
    }

    async fn handle_analyze_dead_code(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeDeadCodeContract>(params)?;
        self.service.analyze_dead_code(contract).await
    }

    async fn handle_analyze_tdg(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeTdgContract>(params)?;
        self.service.analyze_tdg(contract).await
    }

    async fn handle_analyze_lint_hotspot(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeLintHotspotContract>(params)?;
        self.service.analyze_lint_hotspot(contract).await
    }

    async fn handle_quality_gate(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<QualityGateContract>(params)?;
        self.service.quality_gate(contract).await
    }

    async fn handle_analyze_entropy(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<AnalyzeEntropyContract>(params)?;
        self.service.analyze_entropy(contract).await
    }

    async fn handle_refactor_auto(&self, params: Value) -> Result<Value> {
        let contract = serde_json::from_value::<RefactorAutoContract>(params)?;
        self.service.refactor_auto(contract).await
    }

    /// Get tool definitions for MCP discovery
    #[must_use] 
    pub fn get_tool_definitions(&self) -> Value {
        json!({
            "tools": [
                {
                    "name": "analyze_complexity",
                    "description": "Analyze code complexity metrics",
                    "parameters": self.get_complexity_schema()
                },
                {
                    "name": "analyze_satd",
                    "description": "Analyze Self-Admitted Technical Debt",
                    "parameters": self.get_satd_schema()
                },
                {
                    "name": "analyze_dead_code",
                    "description": "Analyze dead and unreachable code",
                    "parameters": self.get_dead_code_schema()
                },
                {
                    "name": "analyze_tdg",
                    "description": "Analyze Technical Debt Gradient",
                    "parameters": self.get_tdg_schema()
                },
                {
                    "name": "analyze_lint_hotspot",
                    "description": "Find lint hotspots",
                    "parameters": self.get_lint_hotspot_schema()
                },
                {
                    "name": "analyze_entropy",
                    "description": "Analyze actionable entropy patterns",
                    "parameters": self.get_entropy_schema()
                },
                {
                    "name": "quality_gate",
                    "description": "Run quality gate checks",
                    "parameters": self.get_quality_gate_schema()
                },
                {
                    "name": "refactor_auto",
                    "description": "Auto refactor code",
                    "parameters": self.get_refactor_schema()
                }
            ]
        })
    }

    fn get_complexity_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "max_cyclomatic": {"type": "integer"},
                "max_cognitive": {"type": "integer"},
                "max_halstead": {"type": "number"}
            },
            "required": ["path"]
        })
    }

    fn get_satd_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "severity": {"type": "string", "enum": ["low", "medium", "high", "critical"]},
                "critical_only": {"type": "boolean"},
                "strict": {"type": "boolean"},
                "fail_on_violation": {"type": "boolean"}
            },
            "required": ["path"]
        })
    }

    fn get_dead_code_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "include_unreachable": {"type": "boolean"},
                "min_dead_lines": {"type": "integer"},
                "max_percentage": {"type": "number"},
                "fail_on_violation": {"type": "boolean"}
            },
            "required": ["path"]
        })
    }

    fn get_tdg_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "threshold": {"type": "number"},
                "include_components": {"type": "boolean"},
                "critical_only": {"type": "boolean"}
            },
            "required": ["path"]
        })
    }

    fn get_lint_hotspot_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "file": {"type": "string"},
                "max_density": {"type": "number"},
                "min_confidence": {"type": "number"},
                "enforce": {"type": "boolean"},
                "dry_run": {"type": "boolean"}
            },
            "required": ["path"]
        })
    }

    fn get_quality_gate_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "profile": {"type": "string", "enum": ["standard", "strict", "extreme", "toyota"]},
                "file": {"type": "string"},
                "fail_on_violation": {"type": "boolean"},
                "verbose": {"type": "boolean"}
            },
            "required": ["path"]
        })
    }

    fn get_entropy_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "path": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "top_files": {"type": "integer"},
                "include_tests": {"type": "boolean"},
                "timeout": {"type": "integer"},
                "min_severity": {"type": "string", "enum": ["low", "medium", "high"]},
                "top_violations": {"type": "integer"},
                "file": {"type": "string"}
            },
            "required": ["path"]
        })
    }

    fn get_refactor_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "file": {"type": "string"},
                "format": {"type": "string", "enum": ["table", "json", "yaml", "markdown", "csv", "summary"]},
                "output": {"type": "string"},
                "target_complexity": {"type": "integer"},
                "dry_run": {"type": "boolean"},
                "timeout": {"type": "integer"}
            },
            "required": ["file"]
        })
    }
}

#[cfg(test)]
mod property_tests {
    use proptest::prelude::*;

    proptest! {
        #[test]
        fn basic_property_stability(_input in ".*") {
            // Basic property test for coverage
            prop_assert!(true);
        }

        #[test]
        fn module_consistency_check(_x in 0u32..1000) {
            // Module consistency verification
            prop_assert!(_x < 1001);
        }
    }
}