"""
Module: permission_validator.py
Description: This module provides a PermissionValidator class for validating user permissions
             against required permissions for specific operations within the Genesis system.
"""

import logging
from typing import List, Optional, Dict

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


class PermissionValidator:
    """
    A class for validating user permissions against required permissions.
    """

    def __init__(self, permissions_map: Optional[Dict[str, List[str]]] = None) -> None:
        """
        Initializes the PermissionValidator with an optional permissions map.

        Args:
            permissions_map (Optional[Dict[str, List[str]]]): A dictionary mapping operation names to a list of required permissions.
                                                               If None, an empty dictionary is used.
        """
        self.permissions_map = permissions_map if permissions_map is not None else {}
        logging.info("PermissionValidator initialized with permissions map.")

    def validate_permission(self, user_permissions: List[str], operation: str) -> bool:
        """
        Validates if the user has the required permissions to perform a specific operation.

        Args:
            user_permissions (List[str]): A list of permissions the user possesses.
            operation (str): The name of the operation to be performed.

        Returns:
            bool: True if the user has the required permissions, False otherwise.
        """
        try:
            required_permissions = self.permissions_map.get(operation, [])
            if not required_permissions:
                logging.info(f"No specific permissions required for operation: {operation}. Allowing.")
                return True  # No specific permissions required

            if not user_permissions:
                logging.warning(f"User has no permissions but needs: {required_permissions} for operation: {operation}")
                return False  # User has no permissions

            for permission in required_permissions:
                if permission not in user_permissions:
                    logging.warning(f"User missing permission: {permission} for operation: {operation}")
                    return False  # User is missing a required permission

            logging.info(f"User has all required permissions for operation: {operation}")
            return True  # User has all required permissions

        except Exception as e:
            logging.error(f"Error validating permission for operation {operation}: {e}")
            return False  # General failure


    def add_operation_permissions(self, operation: str, permissions: List[str]) -> None:
        """
        Adds or updates the required permissions for a given operation.

        Args:
            operation (str): The name of the operation.
            permissions (List[str]): A list of required permissions for the operation.
        """
        try:
            self.permissions_map[operation] = permissions
            logging.info(f"Permissions for operation '{operation}' updated to: {permissions}")
        except Exception as e:
            logging.error(f"Error adding/updating permissions for operation {operation}: {e}")


    def remove_operation(self, operation: str) -> None:
         """
         Removes an operation and its associated permissions from the permission map.

         Args:
             operation (str): The name of the operation to remove.
         """
         try:
             if operation in self.permissions_map:
                 del self.permissions_map[operation]
                 logging.info(f"Operation '{operation}' and its permissions removed.")
             else:
                 logging.warning(f"Operation '{operation}' not found in permission map.")
         except Exception as e:
             logging.error(f"Error removing operation {operation}: {e}")


if __name__ == '__main__':
    # Example Usage
    permissions_map = {
        "create_user": ["admin", "create_user"],
        "delete_user": ["admin", "delete_user"],
        "view_data": ["read_only", "admin"]
    }

    validator = PermissionValidator(permissions_map)

    # Test Cases
    user1_permissions = ["admin", "create_user", "read_only"]
    user2_permissions = ["read_only"]
    user3_permissions = ["create_user"]
    user4_permissions = []

    print(f"User 1 can create user: {validator.validate_permission(user1_permissions, 'create_user')}")  # True
    print(f"User 2 can create user: {validator.validate_permission(user2_permissions, 'create_user')}")  # False
    print(f"User 1 can view data: {validator.validate_permission(user1_permissions, 'view_data')}")  # True
    print(f"User 2 can view data: {validator.validate_permission(user2_permissions, 'view_data')}")  # True
    print(f"User 3 can delete user: {validator.validate_permission(user3_permissions, 'delete_user')}") # False
    print(f"User 4 can create user: {validator.validate_permission(user4_permissions, 'create_user')}") # False

    validator.add_operation_permissions("update_user", ["admin", "update_user"])
    print(f"User 1 can update user: {validator.validate_permission(user1_permissions, 'update_user')}")  # False - missing update_user

    validator.remove_operation("view_data")
    print(f"User 2 can view data: {validator.validate_permission(user2_permissions, 'view_data')}") # True - no permissions required

    # Example with no permission map
    validator2 = PermissionValidator()
    print(f"User 1 can do anything with no permission map: {validator2.validate_permission(user1_permissions, 'any_operation')}") # True