"""
 Created on May 19, 2018
 @author: <NAME> <<EMAIL>>
"""

__all__ = ["NssmException", "ServiceException", "ServiceDoesntExistException",
           "ServiceInstallException", "ServiceAlreadyInstalledException",
           "ServiceRemoveException", "ServiceStartException",
           "ServiceStopException", "ServiceResumeException",
           "ServicePauseException", "ServiceConfigurationException",
           "ServiceNotStartedException"]


class NssmException(Exception):
    """
    NSSM generic exception class
    """

    MESSAGE_TEMPLATE = "[{service}] {message}"
    DEFAULT_MESSAGE = "NSSM error occurred"

    def __init__(self, service, message=None, output=None, rcode=None):
        """
        :param service: Service name
        :type service: str
        :param message: Exception message
        :type message: str
        :param output: Console process output message
        :type output: str
        :param rcode: Console process return code
        :type rcode: int
        """
        self.service = service
        self.output = output

        if message is None:
            message = self.DEFAULT_MESSAGE

        message = self.MESSAGE_TEMPLATE.format(service=service,
                                               message=message)
        super(Exception, self).__init__(message)


class ServiceException(NssmException):
    """
    Service base exception
    """
    pass


class ServiceDoesntExistException(ServiceException):
    """
    Service doesn't exist exist exception
    """
    DEFAULT_MESSAGE = "The specified service does not exist as an installed " \
                      "service."


class ServiceInstallException(ServiceException):
    """
    Service install generic exception
    """
    DEFAULT_MESSAGE = "Service installation failed"


class ServiceAlreadyInstalledException(ServiceException):
    """
    Service already created exception
    """
    DEFAULT_MESSAGE = "The specified service already exists"


class ServiceRemoveException(ServiceException):
    """
    Service removal generic exception
    """
    DEFAULT_MESSAGE = "Service removal failed"


class ServiceStartException(ServiceException):
    """
    Service start generic exception
    """
    DEFAULT_MESSAGE = "Service start failed"


class ServiceNotStartedException(ServiceException):
    """
    Service start generic exception
    """
    DEFAULT_MESSAGE = "The service has not been started"


class ServiceStopException(ServiceException):
    """
    Service stop generic exception
    """
    DEFAULT_MESSAGE = "Service stop failed"


class ServicePauseException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service pause failed"


class ServiceResumeException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service resume failed"


class ServiceConfigurationException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service configuration failed"


def _map_exception(command, rcode):
    """
    Map command return codes to exceptions

    :param command: Console command
    :param rcode: Command return code
    :type rcode: int
    :return: Mapped exception class
    :rtype: :class:`NssmException`
    """
    cmd_rc_exception_map = {
        # Install command
        ("install", 5): ServiceAlreadyInstalledException,
        ("install", "*"): ServiceInstallException,

        # Remove command
        ("remove", "*"): ServiceRemoveException,

        # Start command
        ("start", "*"): ServiceStartException,

        # Restart command
        ("restart", "*"): ServiceStartException,

        # Stop command
        ("stop", "*"): ServiceStopException,

        # Pause command
        ("pause", 1): ServiceNotStartedException,
        ("pause", "*"): ServicePauseException,

        # Continue command
        ("continue", 1): ServiceNotStartedException,
        ("continue", "*"): ServiceResumeException,

        # Get/Set command
        ("set", "*"): ServiceConfigurationException,
        ("get", "*"): ServiceConfigurationException,

        # Any command
        ("*", 3): ServiceDoesntExistException,
    }

    # Match exact return command and return code
    try:
        return cmd_rc_exception_map[(command, rcode)]
    except KeyError:
        pass  # Not in the map

    # Try with match-all command
    try:
        return cmd_rc_exception_map[("*", rcode)]
    except KeyError:
        pass  # Not in the map

    # Try with match-all return code
    try:
        return cmd_rc_exception_map[(command, "*")]
    except KeyError:
        pass  # Not in the map

    # Unknown return command and return code pair
    return NssmException

"""
 Created on May 19, 2018
 @author: <NAME> <<EMAIL>>
"""

__all__ = ["NssmException", "ServiceException", "ServiceDoesntExistException",
           "ServiceInstallException", "ServiceAlreadyInstalledException",
           "ServiceRemoveException", "ServiceStartException",
           "ServiceStopException", "ServiceResumeException",
           "ServicePauseException", "ServiceConfigurationException",
           "ServiceNotStartedException"]


class NssmException(Exception):
    """
    NSSM generic exception class
    """

    MESSAGE_TEMPLATE = "[{service}] {message}"
    DEFAULT_MESSAGE = "NSSM error occurred"

    def __init__(self, service, message=None, output=None, rcode=None):
        """
        :param service: Service name
        :type service: str
        :param message: Exception message
        :type message: str
        :param output: Console process output message
        :type output: str
        :param rcode: Console process return code
        :type rcode: int
        """
        self.service = service
        self.output = output

        if message is None:
            message = self.DEFAULT_MESSAGE

        message = self.MESSAGE_TEMPLATE.format(service=service,
                                               message=message)
        super(Exception, self).__init__(message)


class ServiceException(NssmException):
    """
    Service base exception
    """
    pass


class ServiceDoesntExistException(ServiceException):
    """
    Service doesn't exist exist exception
    """
    DEFAULT_MESSAGE = "The specified service does not exist as an installed " \
                      "service."


class ServiceInstallException(ServiceException):
    """
    Service install generic exception
    """
    DEFAULT_MESSAGE = "Service installation failed"


class ServiceAlreadyInstalledException(ServiceException):
    """
    Service already created exception
    """
    DEFAULT_MESSAGE = "The specified service already exists"


class ServiceRemoveException(ServiceException):
    """
    Service removal generic exception
    """
    DEFAULT_MESSAGE = "Service removal failed"


class ServiceStartException(ServiceException):
    """
    Service start generic exception
    """
    DEFAULT_MESSAGE = "Service start failed"


class ServiceNotStartedException(ServiceException):
    """
    Service start generic exception
    """
    DEFAULT_MESSAGE = "The service has not been started"


class ServiceStopException(ServiceException):
    """
    Service stop generic exception
    """
    DEFAULT_MESSAGE = "Service stop failed"


class ServicePauseException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service pause failed"


class ServiceResumeException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service resume failed"


class ServiceConfigurationException(ServiceException):
    """
    Service pause generic exception
    """
    DEFAULT_MESSAGE = "Service configuration failed"


def _map_exception(command, rcode):
    """
    Map command return codes to exceptions

    :param command: Console command
    :param rcode: Command return code
    :type rcode: int
    :return: Mapped exception class
    :rtype: :class:`NssmException`
    """
    cmd_rc_exception_map = {
        # Install command
        ("install", 5): ServiceAlreadyInstalledException,
        ("install", "*"): ServiceInstallException,

        # Remove command
        ("remove", "*"): ServiceRemoveException,

        # Start command
        ("start", "*"): ServiceStartException,

        # Restart command
        ("restart", "*"): ServiceStartException,

        # Stop command
        ("stop", "*"): ServiceStopException,

        # Pause command
        ("pause", 1): ServiceNotStartedException,
        ("pause", "*"): ServicePauseException,

        # Continue command
        ("continue", 1): ServiceNotStartedException,
        ("continue", "*"): ServiceResumeException,

        # Get/Set command
        ("set", "*"): ServiceConfigurationException,
        ("get", "*"): ServiceConfigurationException,

        # Any command
        ("*", 3): ServiceDoesntExistException,
    }

    # Match exact return command and return code
    try:
        return cmd_rc_exception_map[(command, rcode)]
    except KeyError:
        pass  # Not in the map

    # Try with match-all command
    try:
        return cmd_rc_exception_map[("*", rcode)]
    except KeyError:
        pass  # Not in the map

    # Try with match-all return code
    try:
        return cmd_rc_exception_map[(command, "*")]
    except KeyError:
        pass  # Not in the map

    # Unknown return command and return code pair
    return NssmException

Created on May 19, 2018  @author: <NAME> <<EMAIL>> NSSM generic exception class :param service: Service name         :type service: str         :param message: Exception message         :type message: str         :param output: Console process output message         :type output: str         :param rcode: Console process return code         :type rcode: int Service base exception Service doesn't exist exist exception Service install generic exception Service already created exception Service removal generic exception Service start generic exception Service start generic exception Service stop generic exception Service pause generic exception Service pause generic exception Service pause generic exception Map command return codes to exceptions      :param command: Console command     :param rcode: Command return code     :type rcode: int     :return: Mapped exception class     :rtype: :class:`NssmException` # Install command # Remove command # Start command # Restart command # Stop command # Pause command # Continue command # Get/Set command # Any command # Match exact return command and return code # Not in the map # Try with match-all command # Not in the map # Try with match-all return code # Not in the map # Unknown return command and return code pair