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 GoAnalyzer;

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

    fn check_go_import(
        &self,
        node_text: &str,
        node: &Node,
        file_path: &Path,
        source: &str,
        analyzer: &AstAnalyzer,
    ) -> Option<Vulnerability> {
        let lower = node_text.to_lowercase();
        
        if lower.contains("crypto/rsa") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Rsa2048,
                Severity::Medium,
                "crypto/rsa import detected",
                "Migrate to post-quantum cryptography",
                source,
            ));
        }
        
        if lower.contains("crypto/ecdsa") || lower.contains("crypto/elliptic") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Ecdsa,
                Severity::Medium,
                "crypto/ecdsa or crypto/elliptic import detected",
                "Migrate to post-quantum cryptography",
                source,
            ));
        }
        
        if lower.contains("crypto/dsa") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Dsa,
                Severity::Medium,
                "crypto/dsa import detected",
                "Migrate to post-quantum cryptography",
                source,
            ));
        }
        
        if lower.contains("crypto/md5") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Md5,
                Severity::Medium,
                "crypto/md5 import detected",
                "Replace with SHA-256 or SHA-3",
                source,
            ));
        }
        
        if lower.contains("crypto/sha1") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Sha1,
                Severity::Medium,
                "crypto/sha1 import detected",
                "Replace with SHA-256 or SHA-3",
                source,
            ));
        }
        
        if lower.contains("crypto/des") || lower.contains("crypto/rc4") {
            return Some(analyzer.create_vulnerability(
                node,
                file_path,
                VulnerabilityType::Des,
                Severity::High,
                "Weak cipher import detected (DES/RC4)",
                "Replace with AES-256-GCM",
                source,
            ));
        }
        
        // Third-party Go crypto libraries
        if lower.contains("golang.org/x/crypto") {
            if lower.contains("rsa") || lower.contains("ecdsa") {
                return Some(analyzer.create_vulnerability(
                    node,
                    file_path,
                    VulnerabilityType::Rsa2048,
                    Severity::Medium,
                    "golang.org/x/crypto quantum-unsafe algorithm import",
                    "Migrate to post-quantum cryptography",
                    source,
                ));
            }
        }
        
        None
    }
}

impl LanguageAnalyzer for GoAnalyzer {
    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" => {
                // RSA operations
                if node_text.contains("rsa.GenerateKey") || node_text.contains("rsa.GenerateMultiPrimeKey") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Rsa2048,
                        Severity::Critical,
                        "RSA key generation detected",
                        "Migrate to post-quantum key encapsulation (Kyber)",
                        source,
                    ));
                }

                // ECDSA operations
                if node_text.contains("ecdsa.GenerateKey") || node_text.contains("elliptic.") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Ecdsa,
                        Severity::Critical,
                        "ECDSA key generation detected",
                        "Migrate to CRYSTALS-Dilithium for signatures",
                        source,
                    ));
                }

                // DSA operations
                if node_text.contains("dsa.GenerateParameters") || node_text.contains("dsa.GenerateKey") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Dsa,
                        Severity::Critical,
                        "DSA key generation detected",
                        "Migrate to CRYSTALS-Dilithium for signatures",
                        source,
                    ));
                }

                // Weak hash functions
                if node_text.contains("md5.New") || node_text.contains("md5.Sum") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Md5,
                        Severity::High,
                        "MD5 hash function detected",
                        "Replace with SHA-256 or SHA-3",
                        source,
                    ));
                }

                if node_text.contains("sha1.New") || node_text.contains("sha1.Sum") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Sha1,
                        Severity::High,
                        "SHA-1 hash function detected",
                        "Replace with SHA-256 or SHA-3",
                        source,
                    ));
                }

                // Weak ciphers
                if node_text.contains("des.NewCipher") || node_text.contains("des.NewTripleDESCipher") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Des,
                        Severity::Critical,
                        "DES/3DES cipher detected",
                        "Replace with AES-256-GCM",
                        source,
                    ));
                }

                if node_text.contains("rc4.NewCipher") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::Rc4,
                        Severity::Critical,
                        "RC4 cipher detected",
                        "Replace with AES-256-GCM or ChaCha20-Poly1305",
                        source,
                    ));
                }

                // Weak random
                if node_text.contains("math/rand") && !node_text.contains("crypto/rand") {
                    return Some(analyzer.create_vulnerability(
                        node,
                        file_path,
                        VulnerabilityType::WeakRandom,
                        Severity::Medium,
                        "Non-cryptographic RNG detected (math/rand)",
                        "Use crypto/rand for cryptographic operations",
                        source,
                    ));
                }

                None
            }
            // CRITICAL FIX #3: Go import detection
            "import_spec" | "import_declaration" => {
                self.check_go_import(node_text, node, file_path, source, analyzer)
            }
            "interpreted_string_literal" | "raw_string_literal" => {
                analyzer.check_string_literal(node_text, node, file_path, source, node)
            }
            "int_literal" => {
                analyzer.check_key_size_literal(node_text, node, file_path, source)
            }
            _ => None,
        }
    }
}
