from hawkSoar.common.logger import get_logger

from hawkSoar.storage.db_interface import DBInterface


class ManagerDBInterface(DBInterface):
    """ Common parts of the Manager DB Interface. """

    MANAGER_CONNECTION_TYPES = [
        'test',
        'ingest_task',
        'contain_task',
        'decision_task',
        'include_task',
        'investigate_task',
        'notify_task',
        'record_task',
        'recover_task',
        'utility_task'
    ]

    def __init__(self, config):
        self.config = config

    def _setup_database_mapping(self):
        """ Map CRUD to object."""
        self.connections = {}
        for item in self.MANAGER_CONNECTION_TYPES:
            # object to query and delete stuff from database
            self.connections[item] = ''


class ManagerListener(ManagerDBInterface):
    """ Manager Listener Base Class."""

    CONNECTION_TYPE = 'test'  # Unique for each listener

    def __init__(self, config=None):
        # XXX: this is not needed, since no init is defined above
        # super().__init__(config=config)
        self.additional_setup(config=config)

    def get_next_task(self):
        try:
            task_obj = self.connections[self.CONNECTION_TYPE].get_task()
        except Exception as e:
            self.logger.exception(
                'Could not get next task: {} {}'.format(type(e), str(e)))
            return None
        if task_obj is not None:
            task = task_obj  # Might need to convert or guarantee format/type
            task_id = task_obj.id
            self.connections[self.CONNECTION_TYPE].delete(task_obj.id)
            task = self.post_processing(task, task_id)
            self.logger.info('{}: New task received: {}'.format(
                self.CONNECTION_TYPE, task))
            return task
        return None

    def additional_setup(self, config=None):
        """ Optional additional setup."""
        pass

    def post_processing(self, task, task_id):
        """ Optional post processing of a task."""
        return task


class ManagerListenerAndResponder(ManagerListener):
    """ CONNECTION_TYPE and OUTGOING_CONNECTION_TYPE must be implemented by the sub_class """

    CONNECTION_TYPE = 'test'
    OUTGOING_CONNECTION_TYPE = 'test'

    def post_processing(self, task, task_id):
        self.logger.debug(
            'request received: {} -> {}'.format(self.CONNECTION_TYPE, task_id))
        response = self.get_response(task)
        self.connections[self.OUTGOING_CONNECTION_TYPE].put(
            response, filename='{}'.format(task_id))
        self.logger.debug(
            'response send: {} -> {}'.format(self.OUTGOING_CONNECTION_TYPE, task_id))
        return task

    def get_response(self, task):
        """ This function must be implemented by the sub_class """
        return task
