"""Policy engine implementation for authorization."""

from typing import Dict, Any, Optional
from ..action_registry import ActionSchema, PermissionLevel, RiskLevel
from .policy_decision import PolicyDecision


class SimplePolicyEngine:
    """Simple policy engine for action authorization."""

    def __init__(self, user_role: str = "user", environment: str = "production"):
        """Initialize policy engine.
        
        Args:
            user_role: User role (public, user, admin, system)
            environment: Environment (development, staging, production)
        """
        self.user_role = user_role
        self.environment = environment
        
        # Role hierarchy: system > admin > user > public
        self._role_hierarchy = {
            "public": 0,
            "user": 1,
            "admin": 2,
            "system": 3
        }

    def evaluate(
        self,
        action: ActionSchema,
        parameters: Dict[str, Any],
        context: Optional[Dict[str, Any]] = None
    ) -> PolicyDecision:
        """Evaluate policy for action execution.
        
        Args:
            action: Action schema from registry
            parameters: Action parameters
            context: Optional execution context
            
        Returns:
            PolicyDecision with allowed status and reason
        """
        context = context or {}
        
        # Check 1: Permission level
        if not self._check_permission(action.permission_level):
            return PolicyDecision(
                allowed=False,
                reason=f"Insufficient permissions: requires {action.permission_level.value}, user has {self.user_role}",
                metadata={"required": action.permission_level.value, "actual": self.user_role}
            )
        
        # Check 2: Risk level in production
        if self.environment == "production":
            if action.risk_level == RiskLevel.CRITICAL:
                return PolicyDecision(
                    allowed=False,
                    reason=f"Critical risk actions blocked in production",
                    metadata={"risk_level": action.risk_level.value, "environment": self.environment}
                )
        
        # Check 3: Required parameters present
        missing = [p for p in action.required_params if p not in parameters]
        if missing:
            return PolicyDecision(
                allowed=False,
                reason=f"Missing required parameters: {missing}",
                metadata={"missing_params": missing}
            )
        
        # Check 4: Environment-specific constraints
        if self.environment == "production" and action.risk_level == RiskLevel.HIGH:
            if not action.execution.requires_confirmation:
                return PolicyDecision(
                    allowed=False,
                    reason="High risk actions require confirmation in production",
                    metadata={"risk_level": action.risk_level.value}
                )
        
        # All checks passed
        return PolicyDecision(
            allowed=True,
            reason=f"Action authorized: {action.action_id}",
            metadata={
                "action_id": action.action_id,
                "risk_level": action.risk_level.value,
                "permission_level": action.permission_level.value
            }
        )

    def _check_permission(self, required_permission: PermissionLevel) -> bool:
        """Check if user role meets required permission level.
        
        Args:
            required_permission: Required permission level
            
        Returns:
            True if user has sufficient permissions
        """
        user_level = self._role_hierarchy.get(self.user_role, 0)
        required_level = self._role_hierarchy.get(required_permission.value, 0)
        return user_level >= required_level

    def check_path_safety(self, path: str) -> PolicyDecision:
        """Check if path is safe for operations.
        
        Args:
            path: File path to check
            
        Returns:
            PolicyDecision
        """
        # Block system paths in production
        if self.environment == "production":
            dangerous_paths = ["/etc", "/sys", "/proc", "C:\\Windows", "C:\\System32"]
            for dangerous in dangerous_paths:
                if path.startswith(dangerous):
                    return PolicyDecision(
                        allowed=False,
                        reason=f"System path blocked in production: {path}",
                        metadata={"path": path, "environment": self.environment}
                    )
        
        return PolicyDecision(
            allowed=True,
            reason="Path is safe",
            metadata={"path": path}
        )

    def set_user_role(self, role: str) -> None:
        """Update user role.
        
        Args:
            role: New user role
        """
        if role not in self._role_hierarchy:
            raise ValueError(f"Invalid role: {role}. Must be one of {list(self._role_hierarchy.keys())}")
        self.user_role = role

    def set_environment(self, environment: str) -> None:
        """Update environment.
        
        Args:
            environment: New environment
        """
        valid_envs = ["development", "staging", "production"]
        if environment not in valid_envs:
            raise ValueError(f"Invalid environment: {environment}. Must be one of {valid_envs}")
        self.environment = environment
