""" Custom error types """

from abc import ABCMeta
try:
    from collections.abc import Iterable
except ImportError:
    # for py2
    from collections import Iterable

__all__ = ["IllegalStateException", "InvalidSampleTableFileException",
           "PeppyError", "MissingAmendmentError", "InvalidConfigFileException",
           "SampleTableFileException"]


class PeppyError(Exception):
    """ Base error type for peppy custom errors. """

    __metaclass__ = ABCMeta

    def __init__(self, msg):
        super(PeppyError, self).__init__(msg)


class IllegalStateException(PeppyError):
    """ Occurrence of some illogical/prohibited state within an object. """
    pass


class SampleTableFileException(PeppyError):
    """ Error type for invalid sample annotations file. """
    pass


class InvalidSampleTableFileException(SampleTableFileException):
    """ Error type for invalid sample annotations file. """
    pass


class MissingAmendmentError(PeppyError):
    """ Error when project config lacks a requested subproject. """

    def __init__(self, amendment, defined=None):
        """
        Create exception with missing amendment request.

        :param str amendment: the requested (and missing) amendment
        :param Iterable[str] defined: collection of names of defined amendment
        """
        msg = "Amendment '{}' not found".format(amendment)
        if isinstance(defined, Iterable):
            ctx = "defined amendments(s): {}".\
                format(", ".join(map(str, defined)))
            msg = "{}; {}".format(msg, ctx)
        super(MissingAmendmentError, self).__init__(msg)


class InvalidConfigFileException(PeppyError):
    """ Error type for invalid project config file """
    pass
