#!/usr/bin/env python3
"""
Security Hardening Script for Church Music Database
Implements critical security fixes
"""

import os
import secrets
import sys
import re
from pathlib import Path

def generate_secure_key():
    """Generate cryptographically secure secret key"""
    return secrets.token_hex(32)

def check_env_file_security(env_path):
    """Check if .env file has secure permissions"""
    if not os.path.exists(env_path):
        return False, "File does not exist"
    
    stat_info = os.stat(env_path)
    mode = stat_info.st_mode & 0o777
    
    if mode != 0o600:
        return False, f"Insecure permissions: {oct(mode)}. Should be 0600"
    return True, "OK"

def secure_env_file(env_path):
    """Set secure permissions on .env file"""
    try:
        os.chmod(env_path, 0o600)
        return True
    except Exception as e:
        return False, str(e)

def validate_postgresql_uri(uri):
    """Validate PostgreSQL connection string"""
    if not uri or uri == "":
        return False, "Empty URI"
    
    # Check for default/weak passwords
    weak_patterns = [
        'your_password',
        'password',
        'admin',
        '123456',
        'postgres'
    ]
    
    for pattern in weak_patterns:
        if pattern.lower() in uri.lower():
            return False, f"Weak/default password detected: {pattern}"
    
    # Validate format
    if not uri.startswith('postgresql://'):
        return False, "Invalid PostgreSQL URI format"
    
    return True, "OK"

def main():
    print("╔══════════════════════════════════════════════════════════════╗")
    print("║        SECURITY HARDENING - Critical Fixes                   ║")
    print("╚══════════════════════════════════════════════════════════════╝")
    print()
    
    project_root = Path(__file__).parent
    backend_dir = project_root / "backend"
    env_file = backend_dir / ".env"
    
    issues_found = []
    fixes_applied = []
    
    # Check 1: .env file exists and has secure permissions
    print("🔒 Checking .env file security...")
    if env_file.exists():
        is_secure, msg = check_env_file_security(env_file)
        if not is_secure:
            issues_found.append(f".env file: {msg}")
            if secure_env_file(env_file):
                fixes_applied.append("Set .env permissions to 0600")
                print("  ✓ Fixed: Set secure permissions (0600)")
            else:
                print(f"  ✗ Failed to secure .env file")
        else:
            print("  ✓ .env file has secure permissions")
    else:
        issues_found.append(".env file does not exist")
        print("  ⚠ .env file not found. Use .env.template to create one.")
    
    # Check 2: SECRET_KEY strength
    print("\n🔑 Checking SECRET_KEY...")
    if env_file.exists():
        with open(env_file, 'r') as f:
            content = f.read()
            secret_match = re.search(r'SECRET_KEY=(.+)', content)
            if secret_match:
                secret_key = secret_match.group(1).strip()
                if len(secret_key) < 32:
                    issues_found.append(f"SECRET_KEY is too short ({len(secret_key)} chars, need 64+)")
                    print(f"  ⚠ SECRET_KEY is weak (length: {len(secret_key)})")
                    print(f"  → Generate new key: python3 -c \"import secrets; print(secrets.token_hex(32))\"")
                else:
                    print("  ✓ SECRET_KEY length is adequate")
            else:
                issues_found.append("SECRET_KEY not found in .env")
                print("  ✗ SECRET_KEY not found")
    
    # Check 3: Database password strength
    print("\n🗄️  Checking database password...")
    if env_file.exists():
        with open(env_file, 'r') as f:
            content = f.read()
            uri_match = re.search(r'POSTGRESQL_URI=(.+)', content)
            if uri_match:
                uri = uri_match.group(1).strip()
                is_valid, msg = validate_postgresql_uri(uri)
                if not is_valid:
                    issues_found.append(f"Database URI: {msg}")
                    print(f"  ✗ {msg}")
                else:
                    print("  ✓ Database URI appears secure")
            else:
                issues_found.append("POSTGRESQL_URI not found")
                print("  ✗ POSTGRESQL_URI not configured")
    
    # Check 4: .gitignore exists
    print("\n📝 Checking .gitignore...")
    gitignore = project_root / ".gitignore"
    if gitignore.exists():
        with open(gitignore, 'r') as f:
            content = f.read()
            if '*.env' in content or '.env' in content:
                print("  ✓ .gitignore protects .env files")
            else:
                issues_found.append(".env files not in .gitignore")
                print("  ✗ .env files not protected by .gitignore")
    else:
        issues_found.append(".gitignore does not exist")
        print("  ✗ .gitignore not found")
    
    # Summary
    print("\n" + "="*64)
    print("SUMMARY")
    print("="*64)
    
    if issues_found:
        print(f"\n⚠️  {len(issues_found)} security issue(s) found:")
        for i, issue in enumerate(issues_found, 1):
            print(f"  {i}. {issue}")
    else:
        print("\n✅ No critical security issues found")
    
    if fixes_applied:
        print(f"\n✓ {len(fixes_applied)} fix(es) applied:")
        for fix in fixes_applied:
            print(f"  • {fix}")
    
    print("\n📋 NEXT STEPS:")
    print("  1. Rotate SECRET_KEY immediately if weak")
    print("  2. Update database password if using defaults")
    print("  3. Never commit .env files to git")
    print("  4. Review all environment variables")
    print("  5. Run this script regularly")
    
    return 0 if not issues_found else 1

if __name__ == "__main__":
    sys.exit(main())
