"""
Module: audit_logger.py

Description:
    Provides a centralized audit logging mechanism for the Genesis system, 
    recording sensitive operations for security and compliance purposes.
"""

import logging
import json
from typing import Any, Dict, Optional
import os
from datetime import datetime

# Configure logging
AUDIT_LOG_FILE = "/mnt/e/genesis-system/logs/audit.log"  # Ensure directory exists or handle creation
LOG_LEVEL = os.environ.get("AUDIT_LOG_LEVEL", "INFO").upper()  # Get level from environment
os.makedirs(os.path.dirname(AUDIT_LOG_FILE), exist_ok=True) # Create log directory if it doesn't exist
logging.basicConfig(filename=AUDIT_LOG_FILE, level=LOG_LEVEL, 
                    format='%(asctime)s - %(levelname)s - %(message)s')

class AuditLogger:
    """
    A class for logging audit events related to sensitive operations within the Genesis system.
    """

    def __init__(self, module_name: str):
        """
        Initializes the AuditLogger with a module name.

        Args:
            module_name: The name of the module using the logger.  This helps track
                         the origin of audit events.
        """
        self.logger = logging.getLogger(module_name)
        self.module_name = module_name

    def log_event(self, event_type: str, user: str, details: Optional[Dict[str, Any]] = None) -> None:
        """
        Logs an audit event with specific details.

        Args:
            event_type: A string representing the type of event being logged (e.g., "USER_LOGIN", "DATA_ACCESS").
            user: The username or identifier of the user associated with the event.
            details: An optional dictionary containing additional details about the event.
                     This should include relevant information, such as the specific data accessed,
                     changes made, or resources involved.

        Raises:
            TypeError: If details is not a dictionary.
            ValueError: If event_type or user are empty strings.

        Example:
            >>> audit_logger = AuditLogger("DataProcessingModule")
            >>> audit_logger.log_event("DATA_ACCESS", "user123", {"table": "sensitive_data", "operation": "read"})
        """

        if not isinstance(details, (dict, type(None))):
            raise TypeError("Details must be a dictionary or None.")
        if not event_type:
            raise ValueError("Event type cannot be empty.")
        if not user:
            raise ValueError("User cannot be empty.")

        log_message = {
            "timestamp": datetime.utcnow().isoformat(),
            "module": self.module_name,
            "event_type": event_type,
            "user": user,
            "details": details if details else {}
        }

        try:
            self.logger.info(json.dumps(log_message))
        except Exception as e:
            self.logger.error(f"Failed to log audit event: {e}")

    def log_security_alert(self, alert_type: str, description: str, details: Optional[Dict[str, Any]] = None) -> None:
        """
        Logs a security alert, indicating a potential security breach or vulnerability.

        Args:
            alert_type: A string representing the type of security alert (e.g., "UNAUTHORIZED_ACCESS", "SQL_INJECTION").
            description: A human-readable description of the security alert.
            details: An optional dictionary containing additional details about the alert,
                     such as the IP address of the attacker, the affected resource, or the vulnerability exploited.
        """
        if not isinstance(details, (dict, type(None))):
            raise TypeError("Details must be a dictionary or None.")
        
        log_message = {
            "timestamp": datetime.utcnow().isoformat(),
            "module": self.module_name,
            "alert_type": alert_type,
            "description": description,
            "details": details if details else {}
        }

        try:
            self.logger.warning(json.dumps(log_message))  # Log security alerts as warnings or errors
        except Exception as e:
            self.logger.error(f"Failed to log security alert: {e}")


if __name__ == '__main__':
    # Example Usage:
    audit_logger = AuditLogger("UserManager")
    try:
        audit_logger.log_event("USER_LOGIN", "john.doe", {"ip_address": "192.168.1.100"})
        audit_logger.log_event("PASSWORD_RESET", "jane.doe", {"method": "email", "status": "success"})
        audit_logger.log_event("DATA_ACCESS", "admin", {"table": "users", "operation": "read", "filter": "id=123"})
        audit_logger.log_security_alert("UNAUTHORIZED_ACCESS", "Attempted access to sensitive data.", {"ip_address": "10.0.0.5"})

        # Example of a failed log
        # audit_logger.log_event("DATA_MOD", "admin", "string") # This will raise a TypeError

    except Exception as e:
        print(f"An error occurred: {e}")