import httpx
from aext_panels_server.const import PANEL_PACKAGE_MINIMUM_VERSION


def camel_to_snake(s):
    return "".join(["_" + c.lower() if c.isupper() else c for c in s]).lstrip("_")


class JupyterLabPAException(Exception):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Something went wrong"

    def __init__(self, message=None, status=None, code=None, data=None):
        self.status = status or self.default_status
        self.code = code or camel_to_snake(self.__class__.__name__)
        self.message = message or self.default_message or ""
        self.data = data or {}


class CantRetrieveCondaPackages(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Can't retrieve Conda Packages"


class CantGenerateCondaPackages(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Can't generate Conda Packages"


class CondaEnvironmentNotFound(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Conda environment not found"


class CantCreateZipFile(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Can't create project zip file"


class CantRetrieveProjectInfo(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Can't retrieve Project info"


class FailedSavingProjectInfo(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Can't save Project info"


class FileNotFound(JupyterLabPAException):
    default_status = httpx.codes.NOT_FOUND.value
    default_message = "File not found"


class InvalidProjectVersion(JupyterLabPAException):
    default_status = httpx.codes.INTERNAL_SERVER_ERROR.value
    default_message = "Invalid Project version"


class InvalidPanelVersion(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = f"The Panel version is incompatible. Make sure to use a version > {PANEL_PACKAGE_MINIMUM_VERSION}"


class PanelNotInstalled(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = "The Panel package was not found."


class NbconvertNotInstalled(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = "The nbconvert package was not found."


class CantCreateProject(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = "Can't create new project"


class CantUpdateProject(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = "Can't update project"


class CantCreateProjectVersion(JupyterLabPAException):
    default_status = httpx.codes.BAD_REQUEST.value
    default_message = "Can't create new project version"


class Unauthorized(JupyterLabPAException):
    default_status = httpx.codes.UNAUTHORIZED.value
    default_message = "Not authenticated"
