"""This module contains the custom errors for the ``saba`` discrete_app"""


class SabaErrorMixin:
    """A mixin to inject a ``user_message`` into our custom errors"""

    def __init__(self, *args, **kwargs):
        """Set the ``user_message`` from kwargs or default value"""

        self.user_message = kwargs.get('user_message', 'Unknown error between NAO and NAD')

        # ``Exception`` does not take keyword arguments
        super().__init__(*args)


class MissingSabaDataError(SabaErrorMixin, TypeError):
    """When we are missing an expected data from Saba"""

    pass


class MissingMTPDataError(SabaErrorMixin, TypeError):
    """When we are missing an expected data from MTP"""

    pass


class MissingKeyInDataError(SabaErrorMixin, KeyError):
    """Augmented KeyError for `AssessmentsResultsToSabaTask.data` parsing"""

    pass


class ExemptOrRecommendedCourseError(SabaErrorMixin, Exception):
    """An error that occurred while setting exempt or recommended courses

    Parameters
    ----------
    step: str
        The name of the failing step
    step_data: list(dict)
        The courses process results data structure for the step
        See ``tasks.set_mandatory_courses`` for format.

    """

    def __init__(self, step, step_data):
        """Build a customized error message from ``step_data``

        Notes
        -----
        ``error_message`` should look like:
        "Course 2013-06-SALE-FLL1E1: OK
         Course 2013-06-SALE-FLL1E2: KO (Error description)"
        This is because we need to output all error into a single CSV cell later.

        """

        error_message = user_message = ''

        if step == 'set_mandatory_courses':
            user_message = 'Error while setting mandatory course(s) in NAO'
        elif step == 'set_exempt_courses':
            user_message = 'Error while setting exempt course(s) in NAO'

        for course in step_data:
            if course.get('success'):
                error_message += 'Course %s: OK' % course.get('external_id')
            else:
                error_message += 'Course %s: KO (%s)' % (
                    course.get('external_id'),
                    course.get('exception'),
                )
            error_message += ' \n '

        super().__init__(error_message, user_message=user_message)
