"""
Tano Shield Error Classes
"""

class TanoShieldError(Exception):
    """
    Base error class for Tano Shield
    """
    
    def __init__(self, message, code='UNKNOWN_ERROR', status=None, data=None):
        """
        Initialize a new TanoShieldError
        
        Args:
            message (str): Error message
            code (str, optional): Error code. Defaults to 'UNKNOWN_ERROR'.
            status (int, optional): HTTP status code. Defaults to None.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message)
        self.code = code
        self.status = status
        self.data = data
    
    def __str__(self):
        """String representation of the error"""
        if self.status:
            return f"{self.message} (Status: {self.status}, Code: {self.code})"
        return f"{self.message} (Code: {self.code})"

class AuthenticationError(TanoShieldError):
    """
    Authentication error
    """
    
    def __init__(self, message='Authentication failed', data=None):
        """
        Initialize a new AuthenticationError
        
        Args:
            message (str, optional): Error message. Defaults to 'Authentication failed'.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message, 'AUTHENTICATION_ERROR', 401, data)

class ApiRequestError(TanoShieldError):
    """
    API request error
    """
    
    def __init__(self, message='API request failed', status=None, data=None):
        """
        Initialize a new ApiRequestError
        
        Args:
            message (str, optional): Error message. Defaults to 'API request failed'.
            status (int, optional): HTTP status code. Defaults to None.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message, 'API_REQUEST_ERROR', status, data)

class InsufficientCreditsError(TanoShieldError):
    """
    Insufficient credits error
    """
    
    def __init__(self, message='Insufficient credits', data=None):
        """
        Initialize a new InsufficientCreditsError
        
        Args:
            message (str, optional): Error message. Defaults to 'Insufficient credits'.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message, 'INSUFFICIENT_CREDITS', 402, data)

class ValidationError(TanoShieldError):
    """
    Validation error
    """
    
    def __init__(self, message='Validation failed', data=None):
        """
        Initialize a new ValidationError
        
        Args:
            message (str, optional): Error message. Defaults to 'Validation failed'.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message, 'VALIDATION_ERROR', 400, data)

class RateLimitError(TanoShieldError):
    """
    Rate limit error
    """
    
    def __init__(self, message='Rate limit exceeded', data=None):
        """
        Initialize a new RateLimitError
        
        Args:
            message (str, optional): Error message. Defaults to 'Rate limit exceeded'.
            data (any, optional): Additional error data. Defaults to None.
        """
        super().__init__(message, 'RATE_LIMIT_ERROR', 429, data)

def create_error_from_response(response, default_message='API request failed'):
    """
    Create an error from an API response
    
    Args:
        response: The API response
        default_message (str, optional): Default error message. Defaults to 'API request failed'.
    
    Returns:
        TanoShieldError: The appropriate error instance
    """
    status = response.status_code
    
    try:
        error_data = response.json()
    except Exception:
        error_data = None
    
    message = error_data.get('error') or error_data.get('message') or default_message if error_data else default_message
    
    if status == 401:
        return AuthenticationError(message, error_data)
    elif status == 402:
        return InsufficientCreditsError(message, error_data)
    elif status == 400:
        return ValidationError(message, error_data)
    elif status == 429:
        return RateLimitError(message, error_data)
    else:
        return ApiRequestError(message, status, error_data)