//! CLI implementation using uniform contracts
//! This provides a contract-based CLI executor that uses the uniform contract system

#![cfg_attr(coverage_nightly, coverage(off))]
use super::{
    AnalyzeComplexityContract, AnalyzeDeadCodeContract, AnalyzeLintHotspotContract,
    AnalyzeSatdContract, AnalyzeTdgContract, ContractValidation,
};
use crate::cli::{commands::AnalyzeCommands, Commands};
use anyhow::Result;
use std::sync::Arc;

/// CLI handler that uses contracts for consistent parameter processing
pub struct ContractCliHandler {
    service: Arc<crate::contracts::service::ContractService>,
}

impl ContractCliHandler {
    pub fn new() -> Result<Self> {
        Ok(Self {
            service: Arc::new(crate::contracts::service::ContractService::new()?),
        })
    }

    /// Process CLI commands using uniform contracts
    pub async fn handle_command(&self, cmd: Commands) -> Result<()> {
        if let Commands::Analyze(analyze_cmd) = cmd {
            self.handle_analyze_command(analyze_cmd).await
        } else {
            // Execute command without contracts
            println!("🚧 Executing command in standard mode");
            Ok(())
        }
    }

    /// Handle analyze subcommands
    async fn handle_analyze_command(&self, cmd: AnalyzeCommands) -> Result<()> {
        // Print deprecation warnings if any
        let warnings = super::adapter::ContractAdapter::deprecation_warnings(&cmd);
        for warning in warnings {
            eprintln!("{warning}");
        }

        // Process based on command type
        let result = match cmd {
            AnalyzeCommands::Complexity { .. } => self.handle_complexity_analysis(&cmd).await?,
            AnalyzeCommands::Satd { .. } => self.handle_satd_analysis(&cmd).await?,
            AnalyzeCommands::DeadCode { .. } => self.handle_dead_code_analysis(&cmd).await?,
            AnalyzeCommands::Tdg { .. } => self.handle_tdg_analysis(&cmd).await?,
            AnalyzeCommands::LintHotspot { .. } => self.handle_lint_hotspot_analysis(&cmd).await?,
            _ => {
                // Execute analysis in standard mode
                println!("📊 Running analysis in standard mode");
                serde_json::Value::Null
            }
        };

        // Output result
        self.output_result(result, &cmd)?;
        Ok(())
    }

    async fn handle_complexity_analysis(&self, cmd: &AnalyzeCommands) -> Result<serde_json::Value> {
        let contract = super::adapter::ContractAdapter::from_cli(cmd)?;
        if let Some(complexity_contract) = contract
            .as_any()
            .downcast_ref::<AnalyzeComplexityContract>()
        {
            self.service
                .analyze_complexity(complexity_contract.clone())
                .await
        } else {
            Err(anyhow::anyhow!(
                "Invalid contract type for complexity analysis"
            ))
        }
    }

    async fn handle_satd_analysis(&self, cmd: &AnalyzeCommands) -> Result<serde_json::Value> {
        let contract = super::adapter::ContractAdapter::from_cli(cmd)?;
        if let Some(satd_contract) = contract.as_any().downcast_ref::<AnalyzeSatdContract>() {
            self.service.analyze_satd(satd_contract.clone()).await
        } else {
            Err(anyhow::anyhow!("Invalid contract type for SATD analysis"))
        }
    }

    async fn handle_dead_code_analysis(&self, cmd: &AnalyzeCommands) -> Result<serde_json::Value> {
        let contract = super::adapter::ContractAdapter::from_cli(cmd)?;
        if let Some(dead_code_contract) =
            contract.as_any().downcast_ref::<AnalyzeDeadCodeContract>()
        {
            self.service
                .analyze_dead_code(dead_code_contract.clone())
                .await
        } else {
            Err(anyhow::anyhow!(
                "Invalid contract type for dead code analysis"
            ))
        }
    }

    async fn handle_tdg_analysis(&self, cmd: &AnalyzeCommands) -> Result<serde_json::Value> {
        let contract = super::adapter::ContractAdapter::from_cli(cmd)?;
        if let Some(tdg_contract) = contract.as_any().downcast_ref::<AnalyzeTdgContract>() {
            self.service.analyze_tdg(tdg_contract.clone()).await
        } else {
            Err(anyhow::anyhow!("Invalid contract type for TDG analysis"))
        }
    }

    async fn handle_lint_hotspot_analysis(
        &self,
        cmd: &AnalyzeCommands,
    ) -> Result<serde_json::Value> {
        let contract = super::adapter::ContractAdapter::from_cli(cmd)?;
        if let Some(lint_contract) = contract
            .as_any()
            .downcast_ref::<AnalyzeLintHotspotContract>()
        {
            self.service
                .analyze_lint_hotspot(lint_contract.clone())
                .await
        } else {
            Err(anyhow::anyhow!(
                "Invalid contract type for lint hotspot analysis"
            ))
        }
    }

    /// Output result based on command configuration
    fn output_result(&self, result: serde_json::Value, cmd: &AnalyzeCommands) -> Result<()> {
        // Get output path if specified
        let output_path = match cmd {
            AnalyzeCommands::Complexity { output, .. }
            | AnalyzeCommands::Satd { output, .. }
            | AnalyzeCommands::DeadCode { output, .. }
            | AnalyzeCommands::Tdg { output, .. }
            | AnalyzeCommands::LintHotspot { output, .. } => output,
            _ => &None,
        };

        // Format and output
        let output_str = match result {
            serde_json::Value::String(s) => s,
            other => serde_json::to_string_pretty(&other)?,
        };

        if let Some(path) = output_path {
            std::fs::write(path, output_str)?;
            println!("Results written to: {}", path.display());
        } else {
            println!("{output_str}");
        }

        Ok(())
    }
}

/// Extension trait to enable downcasting (simplified for now)
trait AsAny {
    fn as_any(&self) -> &dyn std::any::Any;
}

// Note: This is a simplified implementation - proper downcasting would need more work
impl AsAny for Box<dyn ContractValidation> {
    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}

#[cfg_attr(coverage_nightly, coverage(off))]
#[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);
        }
    }
}

#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
    use super::*;
    use std::path::PathBuf;
    use tempfile::TempDir;

    // ==========================================================================
    // Helper functions
    // ==========================================================================

    /// Creates a temporary directory for testing
    fn create_test_dir() -> TempDir {
        tempfile::tempdir().expect("Failed to create temp directory")
    }

    /// Creates a temporary file with content
    fn create_test_file(dir: &TempDir, name: &str, content: &str) -> PathBuf {
        let path = dir.path().join(name);
        std::fs::write(&path, content).expect("Failed to write test file");
        path
    }

    // ==========================================================================
    // ContractCliHandler::new tests
    // ==========================================================================

    #[test]
    fn test_contract_cli_handler_new_succeeds() {
        let result = ContractCliHandler::new();
        assert!(result.is_ok(), "ContractCliHandler::new() should succeed");
    }

    #[test]
    fn test_contract_cli_handler_new_creates_valid_handler() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        // Verify the service is accessible (field exists)
        let _ = &handler.service;
    }

    // ==========================================================================
    // ContractCliHandler::handle_command tests - non-Analyze commands
    // ==========================================================================

    #[tokio::test]
    async fn test_handle_command_generate_returns_ok() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let cmd = Commands::Generate {
            category: "rust".to_string(),
            template: "cli".to_string(),
            params: vec![],
            output: None,
            create_dirs: false,
        };

        let result = handler.handle_command(cmd).await;
        assert!(result.is_ok(), "Generate command should return Ok");
    }

    #[tokio::test]
    async fn test_handle_command_list_returns_ok() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let cmd = Commands::List {
            toolchain: None,
            category: None,
            format: crate::cli::OutputFormat::Table,
        };

        let result = handler.handle_command(cmd).await;
        assert!(result.is_ok(), "List command should return Ok");
    }

    #[tokio::test]
    async fn test_handle_command_search_returns_ok() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let cmd = Commands::Search {
            query: "test".to_string(),
            toolchain: None,
            limit: 10,
        };

        let result = handler.handle_command(cmd).await;
        assert!(result.is_ok(), "Search command should return Ok");
    }

    #[tokio::test]
    async fn test_handle_command_validate_returns_ok() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let cmd = Commands::Validate {
            uri: "rust/cli".to_string(),
            params: vec![],
        };

        let result = handler.handle_command(cmd).await;
        assert!(result.is_ok(), "Validate command should return Ok");
    }

    // ==========================================================================
    // ContractCliHandler::output_result tests
    // ==========================================================================

    #[test]
    fn test_output_result_with_string_value() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::Value::String("Test output".to_string());
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with string value"
        );
    }

    #[test]
    fn test_output_result_with_json_object() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({
            "key": "value",
            "count": 42
        });
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Satd {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::SatdOutputFormat::Summary,
            severity: None,
            critical_only: false,
            include_tests: false,
            strict: false,
            evolution: false,
            days: 30,
            metrics: false,
            output: None,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            extended: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with JSON object"
        );
    }

    #[test]
    fn test_output_result_with_output_file() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"status": "ok"});
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("output.json");

        let cmd = AnalyzeCommands::DeadCode {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::DeadCodeOutputFormat::Json,
            top_files: Some(10),
            include_unreachable: false,
            min_dead_lines: 10,
            include_tests: false,
            output: Some(output_path.clone()),
            fail_on_violation: false,
            max_percentage: 15.0,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            max_depth: 8,
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with output file"
        );
        assert!(output_path.exists(), "Output file should be created");

        let content = std::fs::read_to_string(&output_path).expect("Should read file");
        assert!(content.contains("status"), "File should contain result");
    }

    #[test]
    fn test_output_result_null_value() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::Value::Null;
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Tdg {
            path: temp_dir.path().to_path_buf(),
            threshold: 1.5,
            top_files: 10,
            format: crate::cli::TdgOutputFormat::Table,
            include_components: false,
            output: None,
            critical_only: false,
            verbose: false,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with null value"
        );
    }

    #[test]
    fn test_output_result_array_value() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!([1, 2, 3, "test"]);
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: temp_dir.path().to_path_buf(),
            file: None,
            format: crate::cli::LintHotspotOutputFormat::Summary,
            max_density: 5.0,
            min_confidence: 0.8,
            enforce: false,
            dry_run: false,
            enforcement_metadata: false,
            output: None,
            perf: false,
            clippy_flags: "-W warnings".to_string(),
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with array value"
        );
    }

    #[test]
    fn test_output_result_with_other_command_type() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::Value::String("result".to_string());
        let temp_dir = create_test_dir();

        // Using Churn command which falls into the _ => &None branch
        let cmd = AnalyzeCommands::Churn {
            project_path: temp_dir.path().to_path_buf(),
            days: 30,
            format: crate::models::churn::ChurnOutputFormat::Summary,
            output: None,
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let output = handler.output_result(result, &cmd);
        assert!(
            output.is_ok(),
            "output_result should succeed with Churn command"
        );
    }

    // ==========================================================================
    // output_result - output file path extraction tests
    // ==========================================================================

    #[test]
    fn test_output_result_complexity_output_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"test": true});
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("complexity.json");

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Json,
            output: Some(output_path.clone()),
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    #[test]
    fn test_output_result_satd_output_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"satd": []});
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("satd.json");

        let cmd = AnalyzeCommands::Satd {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::SatdOutputFormat::Json,
            severity: None,
            critical_only: false,
            include_tests: false,
            strict: false,
            evolution: false,
            days: 30,
            metrics: false,
            output: Some(output_path.clone()),
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            extended: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    #[test]
    fn test_output_result_tdg_output_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"tdg_scores": []});
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("tdg.json");

        let cmd = AnalyzeCommands::Tdg {
            path: temp_dir.path().to_path_buf(),
            threshold: 1.5,
            top_files: 10,
            format: crate::cli::TdgOutputFormat::Json,
            include_components: false,
            output: Some(output_path.clone()),
            critical_only: false,
            verbose: false,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    #[test]
    fn test_output_result_lint_hotspot_output_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"hotspots": []});
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("lint.json");

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: temp_dir.path().to_path_buf(),
            file: None,
            format: crate::cli::LintHotspotOutputFormat::Json,
            max_density: 5.0,
            min_confidence: 0.8,
            enforce: false,
            dry_run: false,
            enforcement_metadata: false,
            output: Some(output_path.clone()),
            perf: false,
            clippy_flags: "-W warnings".to_string(),
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    // ==========================================================================
    // AsAny trait implementation tests
    // ==========================================================================

    #[test]
    fn test_as_any_trait_returns_self() {
        // Test that the AsAny trait is implemented correctly
        let temp_dir = create_test_dir();
        let complexity_contract = AnalyzeComplexityContract {
            base: super::super::BaseAnalysisContract {
                path: temp_dir.path().to_path_buf(),
                format: super::super::OutputFormat::Table,
                output: None,
                top_files: Some(10),
                include_tests: false,
                timeout: 60,
            },
            max_cyclomatic: None,
            max_cognitive: None,
            max_halstead: None,
        };

        // Test that the contract validates correctly
        let validation_result = complexity_contract.validate();
        assert!(validation_result.is_ok());
    }

    // ==========================================================================
    // handle_analyze_command tests - deprecation warnings
    // ==========================================================================

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_analyze_command_prints_deprecation_warnings() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        // Create a Complexity command with deprecated project_path
        let cmd = AnalyzeCommands::Complexity {
            path: PathBuf::from("."),
            project_path: Some(temp_dir.path().to_path_buf()),
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        // This should succeed and print deprecation warning (captured in stderr)
        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    // ==========================================================================
    // handle_analyze_command - standard mode fallback tests
    // ==========================================================================

    #[tokio::test]
    async fn test_handle_analyze_command_churn_standard_mode() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Churn {
            project_path: temp_dir.path().to_path_buf(),
            days: 30,
            format: crate::models::churn::ChurnOutputFormat::Summary,
            output: None,
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        // Churn falls into the standard mode path
        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_handle_analyze_command_dag_standard_mode() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Dag {
            dag_type: crate::cli::DagType::FullDependency,
            project_path: temp_dir.path().to_path_buf(),
            output: None,
            max_depth: None,
            target_nodes: None,
            filter_external: false,
            show_complexity: false,
            include_duplicates: false,
            include_dead_code: false,
            enhanced: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    // ==========================================================================
    // Integration-like tests for analysis handlers
    // These tests require full service setup and are marked as ignored for unit tests
    // ==========================================================================

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_complexity_analysis_integration() {
        // This test verifies the error path when contract downcasting fails
        // In practice this shouldn't happen with correct adapter implementation
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        // Create a valid Rust file for analysis
        create_test_file(&temp_dir, "test.rs", "fn main() { println!(\"Hello\"); }");

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        // This should succeed as the adapter creates the correct contract type
        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_satd_analysis_integration() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        // Create a file with SATD comments
        create_test_file(
            &temp_dir,
            "test.rs",
            "// TODO: Fix this later\nfn main() { /* FIXME: urgent */ }",
        );

        let cmd = AnalyzeCommands::Satd {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::SatdOutputFormat::Summary,
            severity: None,
            critical_only: false,
            include_tests: false,
            strict: false,
            evolution: false,
            days: 30,
            metrics: false,
            output: None,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            extended: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_dead_code_analysis_integration() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        create_test_file(
            &temp_dir,
            "test.rs",
            "#[allow(dead_code)]\nfn unused() {}\nfn main() {}",
        );

        let cmd = AnalyzeCommands::DeadCode {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::DeadCodeOutputFormat::Summary,
            top_files: Some(10),
            include_unreachable: false,
            min_dead_lines: 1,
            include_tests: false,
            output: None,
            fail_on_violation: false,
            max_percentage: 50.0,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            max_depth: 8,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_tdg_analysis_integration() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        create_test_file(&temp_dir, "lib.rs", "pub fn foo() -> i32 { 42 }");

        let cmd = AnalyzeCommands::Tdg {
            path: temp_dir.path().to_path_buf(),
            threshold: 0.0,
            top_files: 10,
            format: crate::cli::TdgOutputFormat::Table,
            include_components: false,
            output: None,
            critical_only: false,
            verbose: false,
            ml: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_lint_hotspot_analysis_integration() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        create_test_file(&temp_dir, "main.rs", "fn main() { println!(\"test\"); }");

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: temp_dir.path().to_path_buf(),
            file: None,
            format: crate::cli::LintHotspotOutputFormat::Summary,
            max_density: 10.0,
            min_confidence: 0.5,
            enforce: false,
            dry_run: false,
            enforcement_metadata: false,
            output: None,
            perf: false,
            clippy_flags: "-W warnings".to_string(),
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    // ==========================================================================
    // Error condition tests
    // ==========================================================================

    #[tokio::test]
    async fn test_handle_complexity_analysis_invalid_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");

        let cmd = AnalyzeCommands::Complexity {
            path: PathBuf::from("/nonexistent/path/that/does/not/exist"),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_err(), "Should fail with invalid path");
    }

    #[tokio::test]
    async fn test_handle_satd_analysis_invalid_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");

        let cmd = AnalyzeCommands::Satd {
            path: PathBuf::from("/nonexistent/satd/path"),
            format: crate::cli::SatdOutputFormat::Summary,
            severity: None,
            critical_only: false,
            include_tests: false,
            strict: false,
            evolution: false,
            days: 30,
            metrics: false,
            output: None,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            extended: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_err(), "Should fail with invalid path");
    }

    #[tokio::test]
    async fn test_handle_dead_code_analysis_invalid_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");

        let cmd = AnalyzeCommands::DeadCode {
            path: PathBuf::from("/nonexistent/dead/code/path"),
            format: crate::cli::DeadCodeOutputFormat::Summary,
            top_files: Some(10),
            include_unreachable: false,
            min_dead_lines: 10,
            include_tests: false,
            output: None,
            fail_on_violation: false,
            max_percentage: 15.0,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            max_depth: 8,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_err(), "Should fail with invalid path");
    }

    #[tokio::test]
    async fn test_handle_tdg_analysis_invalid_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");

        let cmd = AnalyzeCommands::Tdg {
            path: PathBuf::from("/nonexistent/tdg/path"),
            threshold: 1.5,
            top_files: 10,
            format: crate::cli::TdgOutputFormat::Table,
            include_components: false,
            output: None,
            critical_only: false,
            verbose: false,
            ml: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_err(), "Should fail with invalid path");
    }

    #[tokio::test]
    async fn test_handle_lint_hotspot_analysis_invalid_path() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: PathBuf::from("/nonexistent/lint/path"),
            file: None,
            format: crate::cli::LintHotspotOutputFormat::Summary,
            max_density: 5.0,
            min_confidence: 0.8,
            enforce: false,
            dry_run: false,
            enforcement_metadata: false,
            output: None,
            perf: false,
            clippy_flags: "-W warnings".to_string(),
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_err(), "Should fail with invalid path");
    }

    // ==========================================================================
    // Edge case tests
    // ==========================================================================

    #[test]
    fn test_output_result_write_to_nested_dir() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({"nested": "test"});
        let temp_dir = create_test_dir();

        // Create nested directory path
        let nested_dir = temp_dir.path().join("nested").join("subdir");
        std::fs::create_dir_all(&nested_dir).expect("Failed to create nested dirs");
        let output_path = nested_dir.join("output.json");

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Json,
            output: Some(output_path.clone()),
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    #[test]
    fn test_output_result_with_empty_json_object() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({});
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
    }

    #[test]
    fn test_output_result_with_deeply_nested_json() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({
            "level1": {
                "level2": {
                    "level3": {
                        "value": 123
                    }
                }
            }
        });
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Satd {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::SatdOutputFormat::Summary,
            severity: None,
            critical_only: false,
            include_tests: false,
            strict: false,
            evolution: false,
            days: 30,
            metrics: false,
            output: None,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            extended: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
    }

    #[test]
    fn test_output_result_with_special_characters_in_string() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result =
            serde_json::Value::String("Test with\nnewlines\tand\ttabs \"quotes\"".to_string());
        let temp_dir = create_test_dir();

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: None,
            format: crate::cli::ComplexityOutputFormat::Summary,
            output: None,
            max_cyclomatic: None,
            max_cognitive: None,
            include: vec![],
            watch: false,
            top_files: 10,
            fail_on_violation: false,
            timeout: 60,
            ml: false,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
    }

    #[test]
    fn test_output_result_with_unicode_content() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let result = serde_json::json!({
            "unicode": "Hello, \u{4e16}\u{754c}! \u{1f600}"
        });
        let temp_dir = create_test_dir();
        let output_path = temp_dir.path().join("unicode.json");

        let cmd = AnalyzeCommands::DeadCode {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::DeadCodeOutputFormat::Json,
            top_files: Some(10),
            include_unreachable: false,
            min_dead_lines: 10,
            include_tests: false,
            output: Some(output_path.clone()),
            fail_on_violation: false,
            max_percentage: 15.0,
            timeout: 60,
            include: vec![],
            exclude: vec![],
            max_depth: 8,
        };

        let output = handler.output_result(result, &cmd);
        assert!(output.is_ok());
        assert!(output_path.exists());
    }

    // ==========================================================================
    // Commands::Context test (not analyzed by ContractCliHandler)
    // ==========================================================================

    #[tokio::test]
    async fn test_handle_command_context_returns_ok() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();

        let cmd = Commands::Context {
            toolchain: None,
            project_path: temp_dir.path().to_path_buf(),
            output: None,
            format: crate::cli::ContextFormat::Markdown,
            include_large_files: false,
            skip_expensive_metrics: false,
            language: None,
            languages: None,
        };

        let result = handler.handle_command(cmd).await;
        assert!(result.is_ok());
    }

    // ==========================================================================
    // Tests with various AnalyzeCommands configurations
    // These tests require full service integration
    // ==========================================================================

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_complexity_with_all_options() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        create_test_file(&temp_dir, "src.rs", "fn complex() { if true { } else { } }");
        let output_path = temp_dir.path().join("out.json");

        let cmd = AnalyzeCommands::Complexity {
            path: temp_dir.path().to_path_buf(),
            project_path: None,
            file: None,
            files: vec![],
            toolchain: Some("rust".to_string()),
            format: crate::cli::ComplexityOutputFormat::Json,
            output: Some(output_path),
            max_cyclomatic: Some(10),
            max_cognitive: Some(15),
            include: vec!["**/*.rs".to_string()],
            watch: false,
            top_files: 5,
            fail_on_violation: true,
            timeout: 120,
            ml: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_satd_with_strict_mode() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        create_test_file(&temp_dir, "code.rs", "// TODO: implement\nfn stub() {}");

        let cmd = AnalyzeCommands::Satd {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::SatdOutputFormat::Json,
            severity: Some(crate::cli::SatdSeverity::High),
            critical_only: true,
            include_tests: true,
            strict: true,
            evolution: false,
            days: 30,
            metrics: true,
            output: None,
            top_files: 20,
            fail_on_violation: true,
            timeout: 90,
            include: vec![],
            exclude: vec!["target/**".to_string()],
            extended: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_dead_code_with_include_unreachable() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        create_test_file(
            &temp_dir,
            "dead.rs",
            "fn used() {}\nfn unused() { unreachable!(); }",
        );

        let cmd = AnalyzeCommands::DeadCode {
            path: temp_dir.path().to_path_buf(),
            format: crate::cli::DeadCodeOutputFormat::Json,
            top_files: None,
            include_unreachable: true,
            min_dead_lines: 1,
            include_tests: true,
            output: None,
            fail_on_violation: true,
            max_percentage: 5.0,
            timeout: 30,
            include: vec![],
            exclude: vec![],
            max_depth: 5,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_tdg_with_critical_only() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        create_test_file(&temp_dir, "tdg.rs", "pub fn api() -> i32 { 1 + 2 }");

        let cmd = AnalyzeCommands::Tdg {
            path: temp_dir.path().to_path_buf(),
            threshold: 2.5,
            top_files: 5,
            format: crate::cli::TdgOutputFormat::Json,
            include_components: true,
            output: None,
            critical_only: true,
            verbose: true,
            ml: false,
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_lint_hotspot_with_enforce() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        create_test_file(&temp_dir, "lint.rs", "fn test() { let x = 1; }");

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: temp_dir.path().to_path_buf(),
            file: None,
            format: crate::cli::LintHotspotOutputFormat::Json,
            max_density: 2.0,
            min_confidence: 0.9,
            enforce: true,
            dry_run: true,
            enforcement_metadata: true,
            output: None,
            perf: true,
            clippy_flags: "-W clippy::pedantic".to_string(),
            top_files: 15,
            include: vec!["src/**".to_string()],
            exclude: vec![],
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    #[ignore = "requires full service integration"]
    async fn test_handle_lint_hotspot_with_specific_file() {
        let handler = ContractCliHandler::new().expect("Handler creation should succeed");
        let temp_dir = create_test_dir();
        let file_path = create_test_file(&temp_dir, "specific.rs", "fn main() {}");

        let cmd = AnalyzeCommands::LintHotspot {
            project_path: temp_dir.path().to_path_buf(),
            file: Some(file_path),
            format: crate::cli::LintHotspotOutputFormat::Summary,
            max_density: 5.0,
            min_confidence: 0.8,
            enforce: false,
            dry_run: false,
            enforcement_metadata: false,
            output: None,
            perf: false,
            clippy_flags: "-W warnings".to_string(),
            top_files: 10,
            include: vec![],
            exclude: vec![],
        };

        let result = handler.handle_analyze_command(cmd).await;
        assert!(result.is_ok());
    }
}
