# -*- coding: utf-8 -*-
"""
CTF 系统自定义异常类

提供统一的异常处理机制，便于错误追踪和响应格式化
"""


class CTFError(Exception):
    """CTF 系统基础异常类
    
    所有自定义异常的基类，提供统一的错误处理接口
    """
    default_message = "操作失败"
    default_code = 500
    
    def __init__(self, message: str = None, code: int = None, details: dict = None):
        """
        Args:
            message: 错误消息
            code: HTTP 状态码
            details: 额外的错误详情
        """
        self.message = message or self.default_message
        self.code = code or self.default_code
        self.details = details or {}
        super().__init__(self.message)
    
    def to_dict(self):
        """转换为字典格式，用于 JSON 响应"""
        result = {
            'status': 'error',
            'message': self.message,
            'code': self.code
        }
        if self.details:
            result['details'] = self.details
        return result


class ValidationError(CTFError):
    """验证错误
    
    用于输入验证失败的情况
    """
    default_message = "输入验证失败"
    default_code = 400
    
    def __init__(self, message: str = None, field: str = None, value=None):
        """
        Args:
            message: 错误消息
            field: 验证失败的字段名
            value: 验证失败的值
        """
        details = {}
        if field:
            details['field'] = field
        if value is not None:
            details['value'] = value
        super().__init__(message, self.default_code, details if details else None)


class NotFoundError(CTFError):
    """资源未找到错误
    
    用于请求的资源不存在的情况
    """
    default_message = "资源不存在"
    default_code = 404
    
    def __init__(self, message: str = None, resource_type: str = None, resource_id=None):
        """
        Args:
            message: 错误消息
            resource_type: 资源类型（如 'challenge', 'user'）
            resource_id: 资源ID
        """
        details = {}
        if resource_type:
            details['resource_type'] = resource_type
        if resource_id is not None:
            details['resource_id'] = resource_id
        super().__init__(message, self.default_code, details if details else None)


class PermissionDeniedError(CTFError):
    """权限不足错误
    
    用于用户没有权限执行操作的情况
    """
    default_message = "权限不足"
    default_code = 403
    
    def __init__(self, message: str = None, required_permission: str = None):
        """
        Args:
            message: 错误消息
            required_permission: 所需的权限
        """
        details = {}
        if required_permission:
            details['required_permission'] = required_permission
        super().__init__(message, self.default_code, details if details else None)


class AuthenticationError(CTFError):
    """认证错误
    
    用于用户未登录或认证失败的情况
    """
    default_message = "请先登录"
    default_code = 401
    
    def __init__(self, message: str = None):
        super().__init__(message, self.default_code)


class AIServiceError(CTFError):
    """AI 服务错误
    
    用于 AI 服务调用失败的情况
    """
    default_message = "AI 服务调用失败"
    default_code = 500
    
    def __init__(self, message: str = None, provider: str = None, error_details: dict = None):
        """
        Args:
            message: 错误消息
            provider: AI 提供商名称
            error_details: 错误详情
        """
        details = error_details or {}
        if provider:
            details['provider'] = provider
        super().__init__(message, self.default_code, details if details else None)


class GenerationError(CTFError):
    """题目生成错误
    
    用于题目生成失败的情况
    """
    default_message = "题目生成失败"
    default_code = 500
    
    def __init__(self, message: str = None, stage: str = None, task_id: str = None):
        """
        Args:
            message: 错误消息
            stage: 生成阶段
            task_id: 任务ID
        """
        details = {}
        if stage:
            details['stage'] = stage
        if task_id:
            details['task_id'] = task_id
        super().__init__(message, self.default_code, details if details else None)


class DeploymentError(CTFError):
    """部署错误
    
    用于 Docker 部署失败的情况
    """
    default_message = "部署失败"
    default_code = 500
    
    def __init__(self, message: str = None, deployment_uuid: str = None, container_id: str = None):
        """
        Args:
            message: 错误消息
            deployment_uuid: 部署UUID
            container_id: 容器ID
        """
        details = {}
        if deployment_uuid:
            details['deployment_uuid'] = deployment_uuid
        if container_id:
            details['container_id'] = container_id
        super().__init__(message, self.default_code, details if details else None)


class DatabaseError(CTFError):
    """数据库错误
    
    用于数据库操作失败的情况
    """
    default_message = "数据库操作失败"
    default_code = 500
    
    def __init__(self, message: str = None, operation: str = None):
        """
        Args:
            message: 错误消息
            operation: 操作类型（如 'create', 'update', 'delete'）
        """
        details = {}
        if operation:
            details['operation'] = operation
        super().__init__(message, self.default_code, details if details else None)


class ConfigurationError(CTFError):
    """配置错误
    
    用于配置缺失或无效的情况
    """
    default_message = "配置错误"
    default_code = 500
    
    def __init__(self, message: str = None, config_key: str = None):
        """
        Args:
            message: 错误消息
            config_key: 配置键名
        """
        details = {}
        if config_key:
            details['config_key'] = config_key
        super().__init__(message, self.default_code, details if details else None)

