class V2RegistryException(Exception):
  def __init__(self, error_code_str, message, detail, http_status_code=400,
               repository=None, scopes=None):
    super(V2RegistryException, self).__init__(message)
    self.http_status_code = http_status_code
    self.repository = repository
    self.scopes = scopes

    self._error_code_str = error_code_str
    self._detail = detail

  def as_dict(self):
    return {
      'code': self._error_code_str,
      'message': self.message,
      'detail': self._detail if self._detail is not None else {},
    }


class BlobUnknown(V2RegistryException):
  def __init__(self, detail=None):
    super(BlobUnknown, self).__init__('BLOB_UNKNOWN',
                                      'blob unknown to registry',
                                      detail,
                                      404)


class BlobUploadInvalid(V2RegistryException):
  def __init__(self, detail=None):
    super(BlobUploadInvalid, self).__init__('BLOB_UPLOAD_INVALID',
                                            'blob upload invalid',
                                            detail)


class BlobUploadUnknown(V2RegistryException):
  def __init__(self, detail=None):
    super(BlobUploadUnknown, self).__init__('BLOB_UPLOAD_UNKNOWN',
                                            'blob upload unknown to registry',
                                            detail,
                                            404)


class DigestInvalid(V2RegistryException):
  def __init__(self, detail=None):
    super(DigestInvalid, self).__init__('DIGEST_INVALID',
                                        'provided digest did not match uploaded content',
                                        detail)


class ManifestBlobUnknown(V2RegistryException):
  def __init__(self, detail=None):
    super(ManifestBlobUnknown, self).__init__('MANIFEST_BLOB_UNKNOWN',
                                              'manifest blob unknown to registry',
                                              detail)


class ManifestInvalid(V2RegistryException):
  def __init__(self, detail=None, http_status_code=400):
    super(ManifestInvalid, self).__init__('MANIFEST_INVALID',
                                          'manifest invalid',
                                          detail,
                                          http_status_code)


class ManifestUnknown(V2RegistryException):
  def __init__(self, detail=None):
    super(ManifestUnknown, self).__init__('MANIFEST_UNKNOWN',
                                          'manifest unknown',
                                          detail,
                                          404)


class ManifestUnverified(V2RegistryException):
  def __init__(self, detail=None):
    super(ManifestUnverified, self).__init__('MANIFEST_UNVERIFIED',
                                             'manifest failed signature verification',
                                             detail)


class NameInvalid(V2RegistryException):
  def __init__(self, detail=None):
    super(NameInvalid, self).__init__('NAME_INVALID',
                                      'invalid repository name',
                                      detail)


class NameUnknown(V2RegistryException):
  def __init__(self, detail=None):
    super(NameUnknown, self).__init__('NAME_UNKNOWN',
                                      'repository name not known to registry',
                                      detail,
                                      404)


class SizeInvalid(V2RegistryException):
  def __init__(self, detail=None):
    super(SizeInvalid, self).__init__('SIZE_INVALID',
                                      'provided length did not match content length',
                                      detail)


class TagAlreadyExists(V2RegistryException):
  def __init__(self, detail=None):
    super(TagAlreadyExists, self).__init__('TAG_ALREADY_EXISTS',
                                           'tag was already pushed',
                                           detail,
                                           409)

class TagInvalid(V2RegistryException):
  def __init__(self, detail=None):
    super(TagInvalid, self).__init__('TAG_INVALID',
                                     'manifest tag did not match URI',
                                     detail)


class Unauthorized(V2RegistryException):
  def __init__(self, detail=None, repository=None, scopes=None):
    super(Unauthorized, self).__init__('UNAUTHORIZED',
                                       'access to the requested resource is not authorized',
                                       detail,
                                       401,
                                       repository=repository,
                                       scopes=scopes)


class Unsupported(V2RegistryException):
  def __init__(self, detail=None):
    super(Unsupported, self).__init__('UNSUPPORTED',
                                      'The operation is unsupported.',
                                      detail,
                                      405)