"""
This module contains a mock resolver that returns mock functions for operations it cannot resolve.
"""

import functools
import logging

from connexion.resolver import Resolution, Resolver, ResolverError

logger = logging.getLogger(__name__)


class MockResolver(Resolver):

    def __init__(self, mock_all):
        super().__init__()
        self.mock_all = mock_all
        self._operation_id_counter = 1

    def resolve(self, operation):
        """
        Mock operation resolver

        :type operation: connexion.operations.AbstractOperation
        """
        operation_id = self.resolve_operation_id(operation)
        if not operation_id:
            # just generate an unique operation ID
            operation_id = f'mock-{self._operation_id_counter}'
            self._operation_id_counter += 1

        mock_func = functools.partial(self.mock_operation, operation=operation)
        if self.mock_all:
            func = mock_func
        else:
            try:
                func = self.resolve_function_from_operation_id(operation_id)
                msg = "... Successfully resolved operationId '{}'! Mock is *not* used for this operation.".format(
                    operation_id)
                logger.debug(msg)
            except ResolverError as resolution_error:
                logger.debug('... {}! Mock function is used for this operation.'.format(
                    resolution_error.reason.capitalize()))
                func = mock_func
        return Resolution(func, operation_id)

    def mock_operation(self, operation, *args, **kwargs):
        resp, code = operation.example_response()
        if resp is not None:
            return resp, code
        return 'No example response was defined.', code
