from rest_framework import status
from rest_framework.exceptions import APIException

from fwd import settings


class GeneralException(APIException):
    detail_with_arg = "error {}"
    default_code = 999

    def __init__(self, detail=None, code=None, excArgs=None):

        code = code if code is not None else self.default_code
        if excArgs is None:
            super().__init__(detail, code)
        else:
            super().__init__(self.detail_with_arg, code)

        self.excArgs = excArgs

class NotAuthenticatedException(GeneralException):
    status_code = status.HTTP_401_UNAUTHORIZED
    default_code = 4010
    default_detail = 'Authentication failed. Username or password is incorrect'
    detail_with_arg = 'Authentication failed. Username or password is incorrect'

class TrialOneException(GeneralException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4032
    default_detail = 'You have signed up for a trial plan before. Please contact sales for more information'


class PermissionDeniedException(GeneralException):
    status_code = status.HTTP_403_FORBIDDEN
    default_code = 4031
    default_detail = 'Action refuse. Dont have permission to perform this action'


class ServiceUnavailableException(GeneralException):
    status_code = 503
    default_code = 5030
    default_detail = 'Service temporarily unavailable, try again later.'

class ServiceTimeoutException(GeneralException):
    status_code = 503
    default_code = 5031
    default_detail = 'Timeout waiting for the result, try again later.'
    detail_with_arg = '{}'

class LockedEntityException(GeneralException):
    status_code = status.HTTP_423_LOCKED
    default_code = 4231
    default_detail = 'Locked Entity'
    detail_with_arg = '{} has been locked or inactive'


class InvalidException(GeneralException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4001
    default_detail = 'Data Invalid'
    detail_with_arg = '{} invalid'


class RequiredFieldException(GeneralException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4002
    default_detail = 'Field required'
    detail_with_arg = '{} param is required'


class DuplicateEntityException(GeneralException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4041
    default_detail = 'Data duplicate'
    detail_with_arg = '{} duplicate'


class NotFoundException(GeneralException):
    status_code = status.HTTP_404_NOT_FOUND
    default_code = 4042
    default_detail = 'Data not found'
    detail_with_arg = '{} not found'


class NumberOfBoxLimitReachedException(InvalidException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4004
    default_detail = 'Number of box limit reached : 20 for data boxs and 3 for anchor boxs'
    detail_with_arg = 'Number of box limit reached : 20 for data boxs and 3 for anchor boxs'


class BadGatewayException(GeneralException):
    status_code = status.HTTP_502_BAD_GATEWAY
    default_code = 5020
    default_detail = 'Bad gateway. Please contact administrator to support'
    detail_with_arg = 'Bad gateway. Please contact administrator to support'


class FileFormatInvalidException(InvalidException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4006
    default_detail = 'File invalid type'
    detail_with_arg = 'File must have type {}'

class FileContentInvalidException(InvalidException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4007
    default_detail = 'Invalid content file'
    detail_with_arg = 'One of the files is broken, please select other file and try again'

class InvalidDecompressedSizeException(InvalidException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 4008
    default_detail = 'Invalid decompessed file'
    detail_with_arg = '{}x{} is not valid, maximum size for one side is {}'


class TokenExpiredException(GeneralException):
    status_code = status.HTTP_401_UNAUTHORIZED
    default_code = 4106
    default_detail = 'Token expired or invalid'
    detail_with_arg = 'Token expired or invalid'


class LimitReachedException(InvalidException):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 40001
    default_detail = 'Data reach limit'
    detail_with_arg = 'Limit reached. {} limit at {} {}'
