#!/usr/bin/env python3
"""
🔍 ROA2WEB Security Validation Tool
Validates that all security measures are properly implemented and functioning.
"""

import os
import sys
import subprocess
from pathlib import Path

class SecurityValidator:
    """Validates security implementation"""
    
    def __init__(self, repo_path: str = "."):
        self.repo_path = Path(repo_path)
        self.errors = []
        self.warnings = []
        self.checks_passed = 0
        self.total_checks = 0
    
    def check(self, condition: bool, success_msg: str, error_msg: str, is_warning: bool = False):
        """Check a condition and track results"""
        self.total_checks += 1
        if condition:
            print(f"✅ {success_msg}")
            self.checks_passed += 1
        else:
            if is_warning:
                print(f"⚠️  {error_msg}")
                self.warnings.append(error_msg)
            else:
                print(f"❌ {error_msg}")
                self.errors.append(error_msg)
    
    def validate_files_exist(self):
        """Validate that all security files exist"""
        print("\n🔍 Checking Security Files...")
        
        required_files = [
            "security/secrets_scanner.py",
            "security/git_cleanup.py", 
            "security/install_hooks.sh",
            "security/setup_security.sh",
            "security/git_hooks/pre-commit",
            "security/git_hooks/commit-msg",
            "security/README.md",
            "security/SECURITY_PROCEDURES.md"
        ]
        
        for file_path in required_files:
            full_path = self.repo_path / file_path
            self.check(
                full_path.exists(),
                f"Security file exists: {file_path}",
                f"Missing security file: {file_path}"
            )
    
    def validate_gitignore(self):
        """Validate .gitignore security patterns"""
        print("\n🛡️  Checking .gitignore Security...")
        
        gitignore_path = self.repo_path / ".gitignore"
        
        if not gitignore_path.exists():
            self.check(False, "", ".gitignore file missing")
            return
        
        with open(gitignore_path, 'r') as f:
            gitignore_content = f.read()
        
        critical_patterns = [
            "*.env.*",
            "!.env.example", 
            "*.pem",
            "*.key",
            "*secret*",
            "*credential*",
            "*password*",
            ".serena/cache/",
            ".serena/memories/"
        ]
        
        for pattern in critical_patterns:
            self.check(
                pattern in gitignore_content,
                f"Security pattern in .gitignore: {pattern}",
                f"Missing .gitignore pattern: {pattern}",
                is_warning=True
            )
    
    def validate_git_hooks(self):
        """Validate git hooks installation"""
        print("\n🪝 Checking Git Hooks...")
        
        hooks_dir = self.repo_path / ".git" / "hooks"
        
        self.check(
            hooks_dir.exists(),
            "Git hooks directory exists",
            "Git hooks directory missing"
        )
        
        required_hooks = ["pre-commit", "commit-msg"]
        
        for hook in required_hooks:
            hook_path = hooks_dir / hook
            self.check(
                hook_path.exists(),
                f"Git hook installed: {hook}",
                f"Git hook missing: {hook}"
            )
            
            if hook_path.exists():
                self.check(
                    os.access(hook_path, os.X_OK),
                    f"Git hook executable: {hook}",
                    f"Git hook not executable: {hook}"
                )
    
    def validate_scripts_executable(self):
        """Validate that scripts are executable"""
        print("\n🔧 Checking Script Permissions...")
        
        executable_scripts = [
            "security/secrets_scanner.py",
            "security/git_cleanup.py",
            "security/install_hooks.sh",
            "security/setup_security.sh"
        ]
        
        for script in executable_scripts:
            script_path = self.repo_path / script
            if script_path.exists():
                self.check(
                    os.access(script_path, os.X_OK),
                    f"Script executable: {script}",
                    f"Script not executable: {script}"
                )
    
    def validate_scanner_functionality(self):
        """Validate scanner can run"""
        print("\n🔍 Testing Security Scanner...")
        
        try:
            # Import and test scanner
            sys.path.append(str(self.repo_path))
            import security.secrets_scanner as scanner
            
            s = scanner.SecretsScanner(self.repo_path)
            self.check(
                len(s.CRITICAL_PATTERNS) > 0,
                f"Scanner patterns loaded: {len(s.CRITICAL_PATTERNS)} patterns",
                "Scanner patterns not loaded"
            )
            
            self.check(
                len(s.SUSPICIOUS_FILES) > 0,
                f"Scanner file patterns loaded: {len(s.SUSPICIOUS_FILES)} patterns",
                "Scanner file patterns not loaded"
            )
            
        except Exception as e:
            self.check(
                False,
                "Scanner functionality test passed",
                f"Scanner functionality test failed: {e}"
            )
    
    def validate_git_repository(self):
        """Validate git repository status"""
        print("\n📦 Checking Git Repository...")
        
        try:
            # Check if in git repo
            result = subprocess.run(
                ['git', 'status'], 
                cwd=self.repo_path, 
                capture_output=True, 
                check=True
            )
            
            self.check(
                True,
                "Git repository status OK",
                "Git repository issues detected"
            )
            
        except subprocess.CalledProcessError:
            self.check(
                False,
                "Git repository status OK",
                "Not in a valid git repository"
            )
    
    def check_environment_files(self):
        """Check for environment files that should be protected"""
        print("\n🔐 Checking Environment Files...")
        
        # Find .env files
        env_files = []
        for root, dirs, files in os.walk(self.repo_path):
            for file in files:
                if file.endswith('.env') and not file.endswith('.env.example'):
                    rel_path = os.path.relpath(os.path.join(root, file), self.repo_path)
                    env_files.append(rel_path)
        
        for env_file in env_files:
            # Check if file is in git tracking
            try:
                result = subprocess.run(
                    ['git', 'ls-files', env_file],
                    cwd=self.repo_path,
                    capture_output=True,
                    text=True
                )
                
                if result.stdout.strip():
                    self.check(
                        False,
                        "",
                        f"Environment file tracked in git: {env_file}",
                        is_warning=True
                    )
                else:
                    self.check(
                        True,
                        f"Environment file properly ignored: {env_file}",
                        ""
                    )
                    
            except subprocess.CalledProcessError:
                pass
    
    def run_validation(self):
        """Run complete security validation"""
        print("🔒 ROA2WEB Security Validation")
        print("=" * 50)
        
        self.validate_files_exist()
        self.validate_gitignore()
        self.validate_git_hooks()
        self.validate_scripts_executable()
        self.validate_scanner_functionality()
        self.validate_git_repository()
        self.check_environment_files()
        
        # Print summary
        print("\n" + "=" * 50)
        print("📊 VALIDATION SUMMARY")
        print("=" * 50)
        
        print(f"✅ Checks passed: {self.checks_passed}/{self.total_checks}")
        
        if self.errors:
            print(f"❌ Errors: {len(self.errors)}")
            for error in self.errors:
                print(f"   • {error}")
        
        if self.warnings:
            print(f"⚠️  Warnings: {len(self.warnings)}")
            for warning in self.warnings:
                print(f"   • {warning}")
        
        # Overall status
        if not self.errors:
            if not self.warnings:
                print("\n🎉 VALIDATION PASSED - Security implementation complete!")
                return True
            else:
                print("\n✅ VALIDATION PASSED - Minor warnings noted")
                return True
        else:
            print("\n❌ VALIDATION FAILED - Critical issues found")
            return False

def main():
    validator = SecurityValidator()
    success = validator.run_validation()
    sys.exit(0 if success else 1)

if __name__ == "__main__":
    main()