# This file is part of project Sverchok. It's copyrighted by the contributors
# recorded in the version control history of the file, available from
# its original location https://github.com/nortikin/sverchok/commit/master
#  
# SPDX-License-Identifier: GPL3
# License-Filename: LICENSE


class SvNoDataError(LookupError):
    """Raised when the node needs data from the socket, but there is no data.
    In most cases, raised only by update system, not by node itself."""
    __description__ = "No data passed to socket"
    def __init__(self, socket=None, node=None, msg=None):

        self.extra_message = msg if msg else ""

        if node is None and socket is not None:
            node = socket.node
        self.node = node
        self.socket = socket

        super(LookupError, self).__init__(self.get_message())

    def get_message(self):
        if self.extra_message:
            return f"node {self.socket.node.name} (socket {self.socket.name}) {self.extra_message}"
        if not self.node and not self.socket:
            return "SvNoDataError"
        else:
            return f"No data passed into socket '{self.socket.name}'"

    def __repr__(self):
        return self.get_message()

    def __str__(self):
        return repr(self)

    def __unicode__(self):
        return repr(self)

    def __format__(self, spec):
        return repr(self)


class CancelError(Exception):
    __description__ = "Aborted by user"
    """Aborting tree evaluation by user"""


class SvProcessingError(Exception):
    """Base exception class for most processing errors in nodes"""
    __description__ = "General processing error"
    pass

class SvInvalidInputException(SvProcessingError):
    """Something wrong in data provided by the user.
    This indicates error of the user, not of the programmer."""
    __description__ = """Invalid input"""
    pass

class SvInvalidResultException(SvProcessingError):
    """Resulting object generated by the node appears to be invalid
    in some sense."""
    __description__ = """Invalid resulting object"""
    pass

class SvExternalLibraryException(SvProcessingError):
    """This exception class is either used to wrap other exceptions
    raised by external libraries, or raised manually when Sverchok
    code is able to detect that something went wrong in the external
    library algorithm."""
    __description__ = "Exception in external library"

class SvUnsupportedOptionException(SvProcessingError):
    """Unsupported option or combination of options selected
    by the user. This usually means that UI of the node is not
    perfect, so the user was able to select some combination of
    options which is not going to work."""
    __description__ = "Unsupported option"

class SvNotFullyConnected(SvProcessingError):
    __description__ = "Not all required inputs are connected"

    def __init__(self, node, sockets):
        self.node = node
        self.sockets = sockets
        socket_names = ", ".join(sockets)
        self.message = "The following inputs are required for node to perform correctly: " + socket_names

    def __str__(self):
        return self.message


class ImplicitConversionProhibited(Exception):
    __description__ = "Implicit sockets conversion is not supported"
    def __init__(self, socket, msg=None):
        self.socket = socket
        self.node = socket.node
        self.from_socket_type = socket.other.bl_idname
        self.to_socket_type = socket.bl_idname
        if msg is None:
            msg = f"Implicit conversion from socket type {self.from_socket_type}" \
                  f" to socket type {self.to_socket_type} is not supported for" \
                  f" socket {socket.name} of node {socket.node.name}. Please" \
                  f" use explicit conversion nodes."
        super().__init__(msg)
        self.message = msg

class DependencyError(Exception):
    """Raised when some library is not installed"""
    __description__ = "Unmet dependency"

class ArgumentError(Exception):
    """Raised when some method is passed with invalid combination
    of arguments. This indicates a programming error."""
    __description__ = "Invalid method arguments"

class InvalidStateError(Exception):
    """Raised when some programmatic object appears to be in
    invalid state; for example, it was not initialized prior
    to calling some method. This indicates a programming error."""
    __description__ = "Erroneous object state"

class AlgorithmError(Exception):
    """Raise when we are in a branch of algorithm that should never happen -
    that indicates that there is a programming error"""
    __description__ = "Error in algorithm"

