#!/usr/bin/env python3
"""
Security Monitor Script
Autonomous monitoring and incident response system
Version: 1.0.0
"""

import os
import sys
import json
import time
import subprocess
import logging
from datetime import datetime
from pathlib import Path

# Configuration
CONFIG_FILE = "security_assistant_config.json"
LOG_FILE = "security_monitor.log"
AUDIT_LOG = "security_audit.log"
MAX_LOG_SIZE = 10 * 1024 * 1024  # 10MB

class SecurityMonitor:
    def __init__(self):
        self.config = self.load_config()
        self.setup_logging()
        self.audit_logger = self.setup_audit_logging()
        
    def load_config(self):
        """Load security assistant configuration"""
        try:
            with open(CONFIG_FILE, 'r') as f:
                config = json.load(f)
            
            # Verify STRICT NO-SHARING policy
            if config.get('security_policy', {}).get('information_sharing') != 'STRICT_NO_SHARING':
                raise ValueError("STRICT NO-SHARING policy not properly configured")
            
            self.log_audit_event("CONFIG_LOADED", "Security configuration loaded successfully")
            return config
        except Exception as e:
            print(f"ERROR: Failed to load configuration: {e}")
            sys.exit(1)
    
    def setup_logging(self):
        """Setup monitoring logging"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler(LOG_FILE),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    
    def setup_audit_logging(self):
        """Setup audit trail logging"""
        audit_logger = logging.getLogger('security_audit')
        audit_logger.setLevel(logging.INFO)
        
        # Create audit log handler
        audit_handler = logging.FileHandler(AUDIT_LOG)
        audit_handler.setFormatter(logging.Formatter('%(asctime)s - AUDIT - %(message)s'))
        
        # Add handler if not already added
        if not audit_logger.handlers:
            audit_logger.addHandler(audit_handler)
            audit_logger.propagate = False
        
        return audit_logger
    
    def log_audit_event(self, event_type, description, details=None):
        """Log security event to audit trail"""
        audit_entry = {
            'timestamp': datetime.now().isoformat(),
            'event_type': event_type,
            'description': description,
            'details': details or {}
        }
        
        self.audit_logger.info(json.dumps(audit_entry))
        self.logger.info(f"AUDIT: {event_type} - {description}")
    
    def check_policy_compliance(self):
        """Verify STRICT NO-SHARING policy compliance"""
        try:
            policy = self.config.get('security_policy', {})
            
            compliance_checks = [
                ("information_sharing", "STRICT_NO_SHARING"),
                ("data_exfiltration", "PROHIBITED"),
                ("external_api_calls", "BLOCKED"),
                ("data_retention", "LOCAL_ONLY")
            ]
            
            for check, expected in compliance_checks:
                if policy.get(check) != expected:
                    raise ValueError(f"Policy violation: {check} = {policy.get(check)}")
            
            self.log_audit_event("POLICY_CHECK", "STRICT NO-SHARING policy verified")
            return True
        except Exception as e:
            self.log_audit_event("POLICY_VIOLATION", f"Policy compliance check failed: {e}")
            return False
    
    def check_email_security(self):
        """Check email security monitor status"""
        try:
            self.logger.info("Checking email security monitor...")
            
            # Check if secure_gmail_monitor.py exists and is running
            if os.path.exists("secure_gmail_monitor.py"):
                result = subprocess.run(
                    ["python3", "secure_gmail_monitor.py", "--status"],
                    capture_output=True,
                    text=True,
                    timeout=30
                )
                
                if result.returncode == 0:
                    self.logger.info("Email security monitor is running")
                    return {"status": "HEALTHY", "details": result.stdout.strip()}
                else:
                    self.logger.warning(f"Email security monitor issue: {result.stderr}")
                    
                    # Autonomous action: Try to restart
                    if self.config['monitoring_targets']['email_security']['autonomous_action'] == 'restart_service':
                        self.log_audit_event("AUTONOMOUS_ACTION", "Attempting to restart email security monitor")
                        restart_result = subprocess.run(
                            ["python3", "secure_gmail_monitor.py", "--start"],
                            capture_output=True,
                            text=True,
                            timeout=60
                        )
                        
                        if restart_result.returncode == 0:
                            return {"status": "RESTARTED", "details": "Service restarted successfully"}
                        else:
                            return {"status": "FAILED", "details": f"Restart failed: {restart_result.stderr}"}
                    else:
                        return {"status": "UNHEALTHY", "details": result.stderr}
            else:
                self.logger.warning("secure_gmail_monitor.py not found")
                return {"status": "NOT_FOUND", "details": "Email security monitor script not found"}
                
        except subprocess.TimeoutExpired:
            self.logger.error("Email security check timed out")
            return {"status": "TIMEOUT", "details": "Check timed out after 30 seconds"}
        except Exception as e:
            self.logger.error(f"Email security check failed: {e}")
            return {"status": "ERROR", "details": str(e)}
    
    def check_system_security(self):
        """Check system security (failed logins, suspicious processes)"""
        checks = []
        
        try:
            # Check failed logins
            self.logger.info("Checking failed logins...")
            failed_logins = subprocess.run(
                ["grep", "Failed password", "/var/log/auth.log"],
                capture_output=True,
                text=True
            )
            
            if failed_logins.returncode == 0:
                failed_count = len(failed_logins.stdout.strip().split('\n')) if failed_logins.stdout.strip() else 0
                checks.append({
                    "check": "failed_logins",
                    "status": "WARNING" if failed_count > 5 else "OK",
                    "details": f"{failed_count} failed login attempts"
                })
            
            # Check suspicious processes
            self.logger.info("Checking for suspicious processes...")
            suspicious_keywords = ["miner", "backdoor", "reverse_shell", "keylogger"]
            suspicious_found = []
            
            for keyword in suspicious_keywords:
                ps_result = subprocess.run(
                    ["ps", "aux"],
                    capture_output=True,
                    text=True
                )
                
                if keyword in ps_result.stdout.lower():
                    suspicious_found.append(keyword)
            
            if suspicious_found:
                checks.append({
                    "check": "suspicious_processes",
                    "status": "CRITICAL",
                    "details": f"Suspicious keywords found: {', '.join(suspicious_found)}"
                })
            else:
                checks.append({
                    "check": "suspicious_processes",
                    "status": "OK",
                    "details": "No suspicious processes detected"
                })
            
            # Check unusual cron jobs
            self.logger.info("Checking cron jobs...")
            cron_result = subprocess.run(
                ["crontab", "-l"],
                capture_output=True,
                text=True
            )
            
            if cron_result.returncode == 0:
                checks.append({
                    "check": "cron_jobs",
                    "status": "OK",
                    "details": f"{len(cron_result.stdout.strip().split('\\n'))} cron jobs"
                })
            
            return checks
            
        except Exception as e:
            self.logger.error(f"System security check failed: {e}")
            return [{"check": "system_security", "status": "ERROR", "details": str(e)}]
    
    def check_network_security(self):
        """Perform basic network security checks"""
        checks = []
        
        try:
            # Check open ports
            self.logger.info("Checking open ports...")
            netstat_result = subprocess.run(
                ["netstat", "-tuln"],
                capture_output=True,
                text=True
            )
            
            if netstat_result.returncode == 0:
                open_ports = len([line for line in netstat_result.stdout.split('\n') if 'LISTEN' in line])
                checks.append({
                    "check": "open_ports",
                    "status": "OK",
                    "details": f"{open_ports} ports listening"
                })
            
            # Check firewall status
            self.logger.info("Checking firewall status...")
            try:
                ufw_result = subprocess.run(
                    ["sudo", "ufw", "status"],
                    capture_output=True,
                    text=True
                )
                
                if "active" in ufw_result.stdout.lower():
                    checks.append({
                        "check": "firewall",
                        "status": "OK",
                        "details": "Firewall is active"
                    })
                else:
                    checks.append({
                        "check": "firewall",
                        "status": "WARNING",
                        "details": "Firewall may not be active"
                    })
            except:
                checks.append({
                    "check": "firewall",
                    "status": "INFO",
                    "details": "Firewall check skipped (sudo required)"
                })
            
            return checks
            
        except Exception as e:
            self.logger.error(f"Network security check failed: {e}")
            return [{"check": "network_security", "status": "ERROR", "details": str(e)}]
    
    def check_gateway_health(self):
        """Check OpenClaw gateway health"""
        try:
            self.logger.info("Checking OpenClaw gateway health...")
            
            # Check if gateway service is running
            gateway_result = subprocess.run(
                ["systemctl", "is-active", "openclaw-gateway"],
                capture_output=True,
                text=True
            )
            
            if gateway_result.returncode == 0 and gateway_result.stdout.strip() == "active":
                return {"status": "HEALTHY", "details": "Gateway service is running"}
            else:
                self.logger.warning(f"Gateway service issue: {gateway_result.stdout}")
                
                # Autonomous action: Try to restart
                if self.config['monitoring_targets']['gateway_health']['autonomous_action'] == 'restart_service':
                    self.log_audit_event("AUTONOMOUS_ACTION", "Attempting to restart OpenClaw gateway")
                    restart_result = subprocess.run(
                        ["sudo", "systemctl", "restart", "openclaw-gateway"],
                        capture_output=True,
                        text=True
                    )
                    
                    if restart_result.returncode == 0:
                        return {"status": "RESTARTED", "details": "Gateway service restarted"}
                    else:
                        return {"status": "FAILED", "details": f"Restart failed: {restart_result.stderr}"}
                else:
                    return {"status": "UNHEALTHY", "details": gateway_result.stdout}
                    
        except Exception as e:
            self.logger.error(f"Gateway health check failed: {e}")
            return {"status": "ERROR", "details": str(e)}
    
    def evaluate_alert_level(self, check_results):
        """Evaluate results and determine alert level"""
        critical_issues = 0
        high_issues = 0
        medium_issues = 0
        
        for result in check_results:
            if isinstance(result, dict):
                status = result.get('status', '').upper()
                
                if status == 'CRITICAL':
                    critical_issues += 1
                elif status == 'WARNING':
                    high_issues += 1
                elif status == 'ERROR':
                    medium_issues += 1
        
        if critical_issues > 0:
            return "CRITICAL"
        elif high_issues > 0:
            return "HIGH"
        elif medium_issues > 0:
            return "MEDIUM"
        else:
            return "LOW"
    
    def take_autonomous_action(self, alert_level, check_results):
        """Take autonomous actions based on alert level"""
        if alert_level == "LOW":
            self.logger.info("Taking autonomous actions for LOW level alerts")
            
            # Log all autonomous actions
            for result in check_results:
                if isinstance(result, dict) and result.get('status') in ['WARNING', 'ERROR']:
                    self.log_audit_event(
                        "AUTONOMOUS_ACTION",
                        f"Handling {result.get('check')} issue",
                        {"status": result.get('status'), "details": result.get('details')}
                    )
            
            return "Autonomous actions completed"
        else:
            self.logger.info(f"Alert level {alert_level} requires human intervention")
            return f"Escalation required for {alert_level} level alert"
    
    def run_monitoring_cycle(self):
        """Run complete monitoring cycle"""
        self.logger.info("=" * 60)
        self.logger.info(f"Starting security monitoring cycle - {datetime.now()}")
        self.logger.info("=" * 60)
        
        # Verify policy compliance
        if not self.check_policy_compliance():
            self.logger.error("Policy compliance check failed. Stopping monitoring.")
            return
        
        check_results = []
        
        # Run all checks
        email_result = self.check_email_security()
        if isinstance(email_result, dict):
            check_results.append(email_result)
        
        system_results = self.check_system_security()
        check_results.extend(system_results)
        
        network_results = self.check_network_security()
        check_results.extend(network_results)
        
        gateway_result = self.check_gateway_health()
        if isinstance(gateway_result, dict):
            check_results.append(gateway_result)
        
        # Evaluate alert level
        alert_level = self.evaluate_alert_level(check_results)
        
        # Log results
        self.logger.info(f"Monitoring complete. Alert level: {alert_level}")
        
        for result in check_results:
            if isinstance(result, dict):
                self.logger.info(f"  - {result.get('check', 'unknown')}: {result.get('status')} - {result.get('details', '')}")
        
        # Take autonomous actions if appropriate
        if alert_level == "LOW":
            action_result = self.take_autonomous_action(alert_level, check_results)
            self.logger.info(f"Autonomous action result: {action_result}")
        
        # Log audit event for monitoring cycle
        self.log_audit_event(
            "MONITORING_CYCLE",
            f"Security monitoring cycle completed - Alert level: {alert_level}",
            {
                "alert_level": alert_level,
                "checks_performed": len(check_results),
                "timestamp": datetime.now().isoformat()
            }
        )
        
        self.logger.info("=" * 60)
        self.logger.info(f"Monitoring cycle completed - {datetime.now()}")
        self.logger.info("=" * 60)
        
        return alert_level, check_results

def main():
    """Main function"""
    monitor = SecurityMonitor()
    
    try:
        alert_level, results = monitor.run_monitoring_cycle()
        
        # Exit with appropriate code
        if alert_level == "CRITICAL":
            sys.exit(100)
        elif alert_level == "HIGH":
            sys.exit(75)
        elif alert_level == "MEDIUM":
            sys.exit(50)
        else:
            sys.exit(0)
            
    except Exception as e:
        monitor.logger.error(f"Monitoring failed: {e}")
        monitor.log_audit_event("MONITORING_FAILURE", f"Monitoring cycle failed: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()