use anyhow::Result;
use std::path::Path;
use tree_sitter::Node;

use crate::analyzers::ast_analyzer::AstAnalyzer;
use crate::types::{Severity, Vulnerability, VulnerabilityType};

use super::LanguageAnalyzer;

pub struct CppAnalyzer;

impl CppAnalyzer {
    pub fn new() -> Self {
        Self
    }

    fn get_c_function_name(&self, node: &Node, source: &str) -> Option<String> {
        let mut cursor = node.walk();
        for child in node.children(&mut cursor) {
            if child.kind() == "identifier" || child.kind() == "field_expression" {
                return child.utf8_text(source.as_bytes()).ok().map(|s| s.to_string());
            }
        }
        None
    }
}

impl LanguageAnalyzer for CppAnalyzer {
    fn check_node(
        &self,
        node: &Node,
        source: &str,
        file_path: &Path,
        analyzer: &AstAnalyzer,
    ) -> Option<Vulnerability> {
        let node_type = node.kind();
        let node_text = match node.utf8_text(source.as_bytes()) {
            Ok(text) => text,
            Err(_) => return None,
        };

        match node_type {
            "call_expression" => {
                // CRITICAL FIX #6: Verify it's actually a function call, not just a mention
                let function_name = self.get_c_function_name(node, source)?;
                
                // OpenSSL RSA functions
                if function_name == "RSA_generate_key" || function_name == "RSA_generate_key_ex" || 
                   function_name == "RSA_new" || function_name == "RSA_generate_multi_prime_key" {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Rsa2048,
                        Severity::Critical,
                        &format!("OpenSSL RSA function {} detected", function_name),
                        "Use liboqs for PQC operations",
                        source,
                    ));
                }

                if function_name == "EC_KEY_new" || function_name == "EC_KEY_new_by_curve_name" ||
                   function_name.starts_with("ECDSA_") || function_name.starts_with("ECDH_") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Ecdsa,
                        Severity::Critical,
                        &format!("OpenSSL EC function {} detected", function_name),
                        "Use liboqs for PQC operations",
                        source,
                    ));
                }

                if function_name.starts_with("DES_") || function_name == "DES_set_key" {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Des,
                        Severity::Critical,
                        &format!("DES function {} detected", function_name),
                        "Replace with AES-256",
                        source,
                    ));
                }

                if function_name.starts_with("MD5_") || function_name == "MD5" {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Md5,
                        Severity::High,
                        &format!("MD5 function {} detected", function_name),
                        "Replace with SHA-256 or SHA-3",
                        source,
                    ));
                }

                if function_name.starts_with("SHA1_") || function_name == "SHA1" {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Sha1,
                        Severity::High,
                        &format!("SHA-1 function {} detected", function_name),
                        "Replace with SHA-256 or SHA-3",
                        source,
                    ));
                }

                if function_name.starts_with("RC4_") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Rc4,
                        Severity::Critical,
                        &format!("RC4 function {} detected", function_name),
                        "Replace with AES-256-GCM or ChaCha20-Poly1305",
                        source,
                    ));
                }

                if function_name == "rand" || function_name == "random" {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::WeakRandom,
                        Severity::Medium,
                        "Non-cryptographic RNG detected (rand/random)",
                        "Use /dev/urandom or RAND_bytes for cryptographic operations",
                        source,
                    ));
                }

                None
            }
            "preproc_include" => {
                if node_text.contains("openssl/rsa.h") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Rsa2048,
                        Severity::Medium,
                        "OpenSSL RSA header included",
                        "Consider liboqs headers",
                        source,
                    ));
                }
                if node_text.contains("openssl/ec.h") || node_text.contains("openssl/ecdsa.h") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Ecdsa,
                        Severity::Medium,
                        "OpenSSL EC header included",
                        "Consider liboqs headers",
                        source,
                    ));
                }
                if node_text.contains("openssl/des.h") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Des,
                        Severity::High,
                        "OpenSSL DES header included",
                        "Use AES instead",
                        source,
                    ));
                }
                if node_text.contains("openssl/md5.h") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Md5,
                        Severity::Medium,
                        "OpenSSL MD5 header included",
                        "Use SHA-256 or SHA-3",
                        source,
                    ));
                }
                None
            }
            "string_literal" => {
                analyzer.check_string_literal(node_text, node, file_path, source, node)
            }
            "number_literal" => {
                analyzer.check_key_size_literal(node_text, node, file_path, source)
            }
            _ => None,
        }
    }
}
