"""
Test module for cryptographic scanner
"""

import pytest
from datetime import datetime, timedelta
from unittest.mock import Mock, patch, MagicMock

from chronos.core.analyze.crypto_scanner import (
    CryptoScanner,
    CipherSuiteInfo,
    CertificateInfo,
    KeyInfo,
    KeyAlgorithm,
    CipherStrength,
    TLSVersion,
    SSLTLSInfo,
    PQCDetectionResult,
    CipherSuiteAnalyzer,
)


class TestKeyInfo:
    """Test key information analysis."""
    
    def test_rsa_key_weak(self):
        """Test weak RSA key detection."""
        key_info = KeyInfo(
            algorithm=KeyAlgorithm.RSA,
            size=1024,
            is_weak=False,
        )
        assert key_info.is_weak is True
        assert key_info.quantum_vulnerable is True
        assert key_info.details["type"] == "RSA"
    
    def test_rsa_key_strong(self):
        """Test strong RSA key."""
        key_info = KeyInfo(
            algorithm=KeyAlgorithm.RSA,
            size=4096,
            is_weak=False,
        )
        assert key_info.is_weak is False
        assert key_info.quantum_vulnerable is True
    
    def test_ecc_key_weak(self):
        """Test weak ECC key detection."""
        key_info = KeyInfo(
            algorithm=KeyAlgorithm.ECC,
            size=192,
            is_weak=False,
        )
        assert key_info.is_weak is True
        assert key_info.quantum_vulnerable is True
    
    def test_ecc_key_strong(self):
        """Test strong ECC key."""
        key_info = KeyInfo(
            algorithm=KeyAlgorithm.ECC,
            size=384,
            is_weak=False,
        )
        assert key_info.is_weak is False
        assert key_info.quantum_vulnerable is True


class TestCipherSuiteInfo:
    """Test cipher suite analysis."""
    
    def test_weak_cipher_detection(self):
        """Test detection of weak ciphers."""
        cipher = CipherSuiteInfo(name="TLS_RSA_WITH_RC4_128_MD5")
        assert cipher.strength == CipherStrength.WEAK
        assert len(cipher.vulnerabilities) > 0
    
    def test_strong_cipher_detection(self):
        """Test detection of strong ciphers."""
        cipher = CipherSuiteInfo(name="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384")
        assert cipher.strength == CipherStrength.STRONG
    
    def test_moderate_cipher_detection(self):
        """Test detection of moderate ciphers."""
        cipher = CipherSuiteInfo(name="TLS_RSA_WITH_3DES_EDE_CBC_SHA")
        # 3DES is actually weak in modern standards due to small block size
        assert cipher.strength == CipherStrength.WEAK


class TestCertificateInfo:
    """Test certificate information parsing."""
    
    def test_certificate_expiry_calculation(self):
        """Test certificate expiry status."""
        now = datetime.utcnow()
        future = now + timedelta(days=30)
        past = now - timedelta(days=1)
        
        # Not expired
        cert = CertificateInfo(
            subject="example.com",
            issuer="CA",
            not_before=now,
            not_after=future,
        )
        assert cert.is_expired is False
        assert cert.days_until_expiry >= 29  # Allow for day boundary
        
        # Expired
        cert_expired = CertificateInfo(
            subject="example.com",
            issuer="CA",
            not_before=past,
            not_after=past,
        )
        assert cert_expired.is_expired is True


class TestSSLTLSInfo:
    """Test SSL/TLS information container."""
    
    def test_vulnerability_tracking(self):
        """Test vulnerability adding."""
        ssl_info = SSLTLSInfo(host="example.com", port=443)
        
        ssl_info.add_vulnerability("Test vulnerability 1")
        ssl_info.add_vulnerability("Test vulnerability 2")
        ssl_info.add_vulnerability("Test vulnerability 1")  # Duplicate
        
        assert len(ssl_info.vulnerabilities) == 2
        assert "Test vulnerability 1" in ssl_info.vulnerabilities


class TestCryptoScanner:
    """Test cryptographic scanner functionality."""
    
    def test_scanner_initialization(self):
        """Test scanner initialization."""
        scanner = CryptoScanner(timeout=15, verbose=True)
        assert scanner.timeout == 15
        assert scanner.verbose is True
    
    def test_cipher_suite_info_parsing(self):
        """Test cipher suite parsing."""
        scanner = CryptoScanner()
        
        # Test weak cipher
        weak = CipherSuiteInfo(name="TLS_RSA_WITH_NULL_MD5")
        assert weak.strength == CipherStrength.WEAK
        
        # Test strong cipher
        strong = CipherSuiteInfo(name="TLS_AES_256_GCM_SHA384")
        assert strong.strength == CipherStrength.STRONG
    
    def test_rsa_key_analysis(self):
        """Test RSA key analysis."""
        scanner = CryptoScanner()
        
        # Weak RSA key
        weak_analysis = scanner.analyze_rsa_key(1024)
        assert weak_analysis["is_weak"] is True
        assert weak_analysis["quantum_vulnerable"] is True
        assert len(weak_analysis["recommendations"]) > 0
        
        # Strong RSA key
        strong_analysis = scanner.analyze_rsa_key(4096)
        assert strong_analysis["is_weak"] is False
        assert strong_analysis["quantum_vulnerable"] is True
    
    def test_ecc_key_analysis(self):
        """Test ECC key analysis."""
        scanner = CryptoScanner()
        
        # Weak ECC key
        weak_analysis = scanner.analyze_ecc_key("secp192r1", 192)
        assert weak_analysis["is_weak"] is True
        assert weak_analysis["quantum_vulnerable"] is True
        
        # Strong ECC key
        strong_analysis = scanner.analyze_ecc_key("secp384r1", 384)
        assert strong_analysis["is_weak"] is False
        assert strong_analysis["quantum_vulnerable"] is True
    
    def test_pqc_detection_result(self):
        """Test PQC detection result."""
        result = PQCDetectionResult(
            found=True,
            algorithms=["CRYSTALS-Kyber"],
            file_path="/config/tls.yaml",
            line_number=42,
            context="key-exchange: ML-KEM",
            confidence=0.95,
            details={"nist_status": "Standardized"},
        )
        
        assert result.found is True
        assert "CRYSTALS-Kyber" in result.algorithms
        assert result.confidence == 0.95
    
    def test_config_file_detection(self):
        """Test configuration file detection."""
        scanner = CryptoScanner()
        
        from pathlib import Path
        
        # Test config file patterns
        assert scanner._is_config_file(Path("config.yaml")) is True
        assert scanner._is_config_file(Path("settings.json")) is True
        assert scanner._is_config_file(Path("deployment.toml")) is True
        assert scanner._is_config_file(Path("app.py")) is False


class TestCipherSuiteAnalyzer:
    """Test cipher suite analyzer."""
    
    def test_weak_cipher_detection(self):
        """Test weak cipher detection."""
        assert CipherSuiteAnalyzer.is_cipher_weak("TLS_RSA_WITH_NULL_MD5") is True
        assert CipherSuiteAnalyzer.is_cipher_weak("TLS_RSA_WITH_RC4_128_MD5") is True
        assert CipherSuiteAnalyzer.is_cipher_weak("TLS_DES_CBC3_SHA") is True
    
    def test_strong_cipher_detection(self):
        """Test strong cipher detection."""
        assert CipherSuiteAnalyzer.is_cipher_weak(
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        ) is False
        assert CipherSuiteAnalyzer.is_cipher_weak(
            "TLS_AES_256_GCM_SHA384"
        ) is False
    
    def test_recommended_cipher_detection(self):
        """Test recommended cipher detection."""
        assert CipherSuiteAnalyzer.is_cipher_recommended(
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        ) is True
        assert CipherSuiteAnalyzer.is_cipher_recommended(
            "TLS_AES_256_GCM_SHA384"
        ) is True
    
    def test_cipher_recommendations(self):
        """Test cipher recommendations generation."""
        ciphers = [
            "TLS_RSA_WITH_RC4_128_MD5",
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        ]
        
        recs = CipherSuiteAnalyzer.get_cipher_recommendations(ciphers)
        
        assert len(recs["weak_ciphers"]) > 0
        assert len(recs["strong_ciphers"]) > 0
        assert "TLS_RSA_WITH_RC4_128_MD5" in recs["weak_ciphers"]
        assert len(recs["recommended"]) > 0


# Async tests require proper pytest-asyncio setup


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
