"""
权限配置加载器

支持从 YAML 配置文件加载权限规则。
"""

import os
from pathlib import Path
from typing import Dict, List, Optional, Union

import yaml

from .permission import PermissionRule, PermissionAction


class PermissionConfigLoader:
    """权限配置加载器"""

    # 默认配置文件路径（相对于项目根目录）
    DEFAULT_CONFIG_PATHS = [
        Path("src/assets/config/permissions.yaml"),
        Path("src/assets/config/permissions.yml"),
        Path("assets/config/permissions.yaml"),
        Path("assets/config/permissions.yml"),
        Path("config/permissions.yaml"),
        Path("config/permissions.yml"),
        Path(".dundun/permissions.yaml"),
        Path(".dundun/permissions.yml"),
    ]

    @classmethod
    def find_config_file(cls, base_dir: Optional[Path] = None) -> Optional[Path]:
        """
        查找配置文件

        Args:
            base_dir: 基础目录，默认为当前工作目录

        Returns:
            配置文件路径，如果未找到则返回 None
        """
        if base_dir is None:
            base_dir = Path.cwd()

        for config_path in cls.DEFAULT_CONFIG_PATHS:
            full_path = base_dir / config_path
            if full_path.exists():
                return full_path

        return None

    @classmethod
    def load(cls, path: Optional[Union[str, Path]] = None) -> Dict:
        """
        加载配置文件

        Args:
            path: 配置文件路径，如果为 None 则自动查找

        Returns:
            配置字典
        """
        if path is None:
            path = cls.find_config_file()
            if path is None:
                return {}

        config_path = Path(path)
        if not config_path.exists():
            return {}

        with open(config_path, encoding="utf-8") as f:
            return yaml.safe_load(f) or {}

    @classmethod
    def build_rules(cls, config: Dict) -> List[PermissionRule]:
        """
        从配置构建规则列表

        Args:
            config: 配置字典

        Returns:
            PermissionRule 列表
        """
        rules = []

        # 处理默认规则
        defaults = config.get("defaults", {})
        for tool, action in defaults.items():
            rules.append(PermissionRule(
                permission=tool,
                pattern="*",
                action=PermissionAction(action) if isinstance(action, str) else action
            ))

        # 处理只读命令白名单
        read_only_commands = config.get("read_only_commands", [])
        for cmd in read_only_commands:
            # 支持字符串或对象格式
            if isinstance(cmd, str):
                rules.append(PermissionRule(
                    permission="bash",
                    pattern=f"{cmd}*",
                    action=PermissionAction.ALLOW
                ))
            elif isinstance(cmd, dict):
                # 对象格式: { command: "ls", action: "allow" }
                for cmd_name, cmd_action in cmd.items():
                    rules.append(PermissionRule(
                        permission="bash",
                        pattern=f"{cmd_name}*",
                        action=PermissionAction(cmd_action) if isinstance(cmd_action, str) else cmd_action
                    ))

        # 处理危险命令黑名单
        dangerous_commands = config.get("dangerous_commands", [])
        for cmd in dangerous_commands:
            if isinstance(cmd, str):
                rules.append(PermissionRule(
                    permission="bash",
                    pattern=cmd,
                    action=PermissionAction.DENY
                ))
            elif isinstance(cmd, dict):
                # 对象格式支持自定义动作
                for cmd_name, cmd_action in cmd.items():
                    action = PermissionAction.DENY
                    if isinstance(cmd_action, str):
                        action = PermissionAction(cmd_action)
                    rules.append(PermissionRule(
                        permission="bash",
                        pattern=cmd_name,
                        action=action
                    ))

        # 处理 Git 写操作
        git_write = config.get("git_write_commands", [])
        for cmd in git_write:
            if isinstance(cmd, str):
                rules.append(PermissionRule(
                    permission="bash",
                    pattern=f"{cmd}*",
                    action=PermissionAction.ASK
                ))
            elif isinstance(cmd, dict):
                for cmd_name, cmd_action in cmd.items():
                    rules.append(PermissionRule(
                        permission="bash",
                        pattern=f"{cmd_name}*",
                        action=PermissionAction(cmd_action) if isinstance(cmd_action, str) else cmd_action
                    ))

        return rules

    @classmethod
    def merge_with_defaults(
        cls,
        config_rules: List[PermissionRule],
        default_rules: List[PermissionRule]
    ) -> List[PermissionRule]:
        """
        合并配置规则和默认规则

        配置规则优先于默认规则。

        Args:
            config_rules: 从配置文件加载的规则
            default_rules: 代码中的默认规则

        Returns:
            合并后的规则列表（配置规则在前，默认规则在后）
        """
        return config_rules + default_rules
