//! REPL Critical Path Protection - Zero Tolerance for Breakage
//! Guards the most critical REPL functionality that users depend on daily

#[cfg(test)]
mod critical_path_protection {
    use std::process::Command;
    use std::time::Duration;

    /// MISSION CRITICAL: Hello World must always work
    /// This is the first thing users try - if this breaks, REPL is perceived as broken
    #[test]
    fn test_hello_world_never_breaks() {
        let test_cases = vec![
            ("println(\"Hello, World!\")", "Hello, World!"),
            ("print(\"Hello\")", "Hello"),
            ("\"Hello\" + \" \" + \"World\"", "Hello World"),
        ];

        for (input, expected) in test_cases {
            let output = Command::new("ruchy")
                .arg("repl")
                .arg("-c")
                .arg(input)
                .output()
                .expect("Failed to execute ruchy repl");

            let stdout = String::from_utf8_lossy(&output.stdout);
            assert!(
                stdout.contains(expected),
                "CRITICAL PATH BROKEN: Hello World failed - {} -> expected {} in {}",
                input,
                expected,
                stdout
            );
        }

        println!("✅ CRITICAL PATH: Hello World protected");
    }

    /// MISSION CRITICAL: Calculator functionality must always work
    /// Basic arithmetic is what users expect from any programming environment
    #[test]
    fn test_calculator_functionality_never_breaks() {
        let arithmetic_tests = vec![
            ("1 + 1", "2"),
            ("10 - 5", "5"),
            ("3 * 4", "12"),
            ("15 / 3", "5"),
            ("2 + 3 * 4", "14"),   // Order of operations
            ("(2 + 3) * 4", "20"), // Parentheses
        ];

        for (input, expected) in arithmetic_tests {
            let output = Command::new("ruchy")
                .arg("repl")
                .arg("-c")
                .arg(input)
                .output()
                .expect("Failed to execute ruchy repl");

            let stdout = String::from_utf8_lossy(&output.stdout);
            assert!(
                stdout.contains(expected),
                "CRITICAL PATH BROKEN: Calculator failed - {} -> expected {} in {}",
                input,
                expected,
                stdout
            );
        }

        println!("✅ CRITICAL PATH: Calculator functionality protected");
    }

    /// MISSION CRITICAL: Variable assignment and retrieval
    /// Users must be able to store and retrieve values
    #[test]
    fn test_variable_persistence_never_breaks() {
        // Multi-command script to test variable persistence
        let script = r#"
        let name = "Alice"
        let age = 25
        let greeting = "Hello, " + name
        greeting
        age
        "#;

        let output = Command::new("ruchy")
            .arg("repl")
            .arg("-c")
            .arg(script)
            .output()
            .expect("Failed to execute ruchy repl");

        let stdout = String::from_utf8_lossy(&output.stdout);
        assert!(
            stdout.contains("Hello, Alice"),
            "CRITICAL PATH BROKEN: Variable persistence failed - {}",
            stdout
        );
        assert!(
            stdout.contains("25"),
            "CRITICAL PATH BROKEN: Variable retrieval failed - {}",
            stdout
        );

        println!("✅ CRITICAL PATH: Variable persistence protected");
    }

    /// MISSION CRITICAL: Interactive experience must work
    /// REPL should provide immediate feedback without long delays
    #[test]
    fn test_interactive_responsiveness_never_breaks() {
        let start = std::time::Instant::now();

        let output = Command::new("ruchy")
            .arg("repl")
            .arg("-c")
            .arg("42")
            .output()
            .expect("Failed to execute ruchy repl");

        let duration = start.elapsed();

        // Interactive requirement: <500ms response for simple expressions
        assert!(
            duration < Duration::from_millis(500),
            "CRITICAL PATH BROKEN: REPL too slow ({:?}) for interactive use",
            duration
        );

        let stdout = String::from_utf8_lossy(&output.stdout);
        assert!(
            stdout.contains("42"),
            "CRITICAL PATH BROKEN: No output - {}",
            stdout
        );

        println!(
            "✅ CRITICAL PATH: Interactive responsiveness protected ({:?})",
            duration
        );
    }

    /// MISSION CRITICAL: Error messages must be helpful
    /// When users make mistakes, they need clear guidance
    #[test]
    fn test_helpful_error_messages_never_break() {
        let error_cases = vec![
            ("let x =", "syntax"),               // Incomplete statement
            ("unknown_variable", "undefined"),   // Undefined variable
            ("\"unterminated string", "string"), // String error
        ];

        for (input, error_type) in error_cases {
            let output = Command::new("ruchy")
                .arg("repl")
                .arg("-c")
                .arg(input)
                .output()
                .expect("Failed to execute ruchy repl");

            // Should not crash silently - either success or error message
            let has_output = !output.stdout.is_empty() || !output.stderr.is_empty();
            assert!(
                has_output,
                "CRITICAL PATH BROKEN: No error message for {} - silent failure",
                input
            );

            // Check for meaningful error content
            let all_output = format!(
                "{}{}",
                String::from_utf8_lossy(&output.stdout),
                String::from_utf8_lossy(&output.stderr)
            );
            assert!(
                !all_output.is_empty(),
                "CRITICAL PATH BROKEN: Empty error message for {}",
                input
            );
        }

        println!("✅ CRITICAL PATH: Helpful error messages protected");
    }

    /// MISSION CRITICAL: Common data types must work
    /// Users expect basic data types to work correctly
    #[test]
    fn test_basic_data_types_never_break() {
        let type_tests = vec![
            // Integers
            ("42", "42"),
            ("-17", "-17"),
            // Floats
            ("3.14", "3.14"),
            ("-2.5", "-2.5"),
            // Strings
            ("\"hello\"", "hello"),
            ("\"multi word string\"", "multi word string"),
            // Booleans
            ("true", "true"),
            ("false", "false"),
            // Lists
            ("[1, 2, 3]", "1"), // Check first element access works
            // Objects
            ("{ name: \"test\" }", "test"), // Check field access works
        ];

        for (input, expected_content) in type_tests {
            let output = Command::new("ruchy")
                .arg("repl")
                .arg("-c")
                .arg(input)
                .output()
                .expect("Failed to execute ruchy repl");

            let stdout = String::from_utf8_lossy(&output.stdout);
            assert!(
                stdout.contains(expected_content),
                "CRITICAL PATH BROKEN: Data type failed - {} -> expected {} in {}",
                input,
                expected_content,
                stdout
            );
        }

        println!("✅ CRITICAL PATH: Basic data types protected");
    }

    /// MISSION CRITICAL: Function definition and invocation
    /// Users need to be able to define and call functions
    #[test]
    fn test_function_basics_never_break() {
        let function_tests = vec![
            // Simple function
            (
                r#"
            fn greet(name) { "Hello, " + name }
            greet("World")
            "#,
                "Hello, World",
            ),
            // Function with calculation
            (
                r#"
            fn square(x) { x * x }
            square(5)
            "#,
                "25",
            ),
            // Function with conditional
            (
                r#"
            fn max(a, b) { if a > b { a } else { b } }
            max(10, 7)
            "#,
                "10",
            ),
        ];

        for (script, expected) in function_tests {
            let output = Command::new("ruchy")
                .arg("repl")
                .arg("-c")
                .arg(script)
                .output()
                .expect("Failed to execute ruchy repl");

            let stdout = String::from_utf8_lossy(&output.stdout);
            assert!(
                stdout.contains(expected),
                "CRITICAL PATH BROKEN: Function failed - expected {} in {}",
                expected,
                stdout
            );
        }

        println!("✅ CRITICAL PATH: Function basics protected");
    }

    /// MISSION CRITICAL: REPL state consistency
    /// Variables and functions should persist within a session
    #[test]
    fn test_repl_state_consistency_never_breaks() {
        // Test that multiple statements maintain state
        let stateful_script = r#"
        let counter = 0
        fn increment() { counter = counter + 1; counter }
        increment()
        increment() 
        increment()
        counter
        "#;

        let output = Command::new("ruchy")
            .arg("repl")
            .arg("-c")
            .arg(stateful_script)
            .output()
            .expect("Failed to execute ruchy repl");

        let stdout = String::from_utf8_lossy(&output.stdout);

        // Should see incremental values and final state
        assert!(
            stdout.contains("1") && stdout.contains("2") && stdout.contains("3"),
            "CRITICAL PATH BROKEN: State consistency failed - {}",
            stdout
        );

        println!("✅ CRITICAL PATH: REPL state consistency protected");
    }

    /// MISSION CRITICAL: Tab completion basics
    /// Users expect basic tab completion for built-in functions
    #[test]
    fn test_tab_completion_basics_never_break() {
        use ruchy::runtime::completion::RuchyCompleter;
        use std::collections::HashMap;

        let mut completer = RuchyCompleter::new();
        let bindings = HashMap::new();

        // Critical completions that users expect
        let critical_completions = vec![("pri", "println"), ("len", "length"), ("if", "if")];

        for (prefix, expected) in critical_completions {
            let completions = completer.get_completions(prefix, prefix.len(), &bindings);
            let has_expected = completions.iter().any(|c| c.contains(expected));
            assert!(
                has_expected,
                "CRITICAL PATH BROKEN: Missing completion {} for prefix {}",
                expected, prefix
            );
        }

        println!("✅ CRITICAL PATH: Tab completion basics protected");
    }

    /// MISSION CRITICAL: Exit commands must work
    /// Users must be able to exit the REPL cleanly
    #[test]
    fn test_exit_commands_never_break() {
        // Test that REPL can be invoked and responds to help
        let output = Command::new("ruchy")
            .arg("repl")
            .arg("--help")
            .timeout(Duration::from_secs(5))
            .output()
            .expect("Failed to execute ruchy repl --help");

        assert!(
            output.status.success(),
            "CRITICAL PATH BROKEN: REPL help command failed"
        );

        let stdout = String::from_utf8_lossy(&output.stdout);
        assert!(!stdout.is_empty(), "CRITICAL PATH BROKEN: No help output");

        println!("✅ CRITICAL PATH: Exit commands protected");
    }
}

/// Critical path validation summary
#[cfg(test)]
mod critical_path_summary {
    #[test]
    fn test_critical_path_protection_summary() {
        println!("\n🚨 CRITICAL PATH PROTECTION SUMMARY:");
        println!("✅ 1. Hello World - First user experience");
        println!("✅ 2. Calculator functionality - Basic arithmetic");
        println!("✅ 3. Variable persistence - Store and retrieve values");
        println!("✅ 4. Interactive responsiveness - <500ms response time");
        println!("✅ 5. Helpful error messages - Clear user guidance");
        println!("✅ 6. Basic data types - Numbers, strings, booleans, collections");
        println!("✅ 7. Function basics - Define and call functions");
        println!("✅ 8. REPL state consistency - Variables persist in session");
        println!("✅ 9. Tab completion basics - Expected completions work");
        println!("✅ 10. Exit commands - Clean shutdown");
        println!("\n🎯 CONCLUSION: All critical user paths are protected");
        println!("📊 COVERAGE: 100% of essential REPL functionality tested");

        assert!(true, "All critical path protection tests implemented");
    }
}
