"""Authorization service for RPC commands.

This module implements identity-based access control for RPC commands.
Configuration is loaded from YAML file with per-identity permissions.
"""

import logging
from pathlib import Path
from typing import Any

yaml: Any

try:
    import yaml
except ImportError:
    yaml = None

logger = logging.getLogger(__name__)


class AuthorizationService:
    """Authorization service for RPC command access control.

    Loads authorization configuration from YAML file and provides
    methods to check if an identity is authorized to execute commands.

    Attributes:
        _config_path: Path to authorization configuration file
        _identities: Dict mapping identity hash to permissions list
    """

    def __init__(self, config_path: str) -> None:
        """Initialize authorization service.

        Args:
            config_path: Path to authorization configuration YAML file
        """
        self._config_path = Path(config_path)
        self._identities: dict[str, list[str]] = {}

        # Load configuration
        self.reload_config()

    def reload_config(self) -> None:
        """Reload authorization configuration from file."""
        if not self._config_path.exists():
            logger.warning(f"Authorization config not found: {self._config_path}")
            self._identities = {}
            return

        if yaml is None:
            logger.error("YAML library not available, cannot load authorization config")
            self._identities = {}
            return

        try:
            with open(self._config_path, 'r') as f:
                config = yaml.safe_load(f)

            if not config or "identities" not in config:
                logger.warning("No identities found in authorization config")
                self._identities = {}
                return

            # Parse identities and permissions
            self._identities = {}
            for identity_config in config["identities"]:
                identity_hash = identity_config.get("hash")
                permissions = identity_config.get("permissions", [])

                if identity_hash:
                    self._identities[identity_hash] = permissions

            logger.info(f"Loaded {len(self._identities)} identities from authorization config")

        except yaml.YAMLError as e:
            logger.error(f"Invalid YAML in authorization config: {e}")
            self._identities = {}
        except Exception as e:
            logger.error(f"Error loading authorization config: {e}")
            self._identities = {}

    def is_authorized(self, identity_hash: str, command: str) -> bool:
        """Check if identity is authorized to execute command.

        Args:
            identity_hash: Identity hash to check
            command: Command name (e.g., "status", "exec", "reboot")

        Returns:
            True if identity is authorized, False otherwise
        """
        # Get permissions for this identity
        permissions = self._identities.get(identity_hash, [])

        # Check if command is in permissions list
        authorized = command in permissions

        if not authorized:
            logger.warning(
                f"Authorization denied: identity={identity_hash[:8]}... "
                f"command={command}"
            )

        return authorized

    def get_permissions(self, identity_hash: str) -> list[str]:
        """Get list of allowed commands for identity.

        Args:
            identity_hash: Identity hash to query

        Returns:
            List of allowed command names
        """
        return self._identities.get(identity_hash, [])

    def get_identity_count(self) -> int:
        """Get number of configured identities.

        Returns:
            Count of identities in configuration
        """
        return len(self._identities)
