

import os
import sys
import json

from hawkSoar.common.logger import get_logger
from hawkSoar.common.process import ExceptionSafeProcess
from hawkSoar.plugins.base import BasePlugin
from hawkSoar.lib.query_parser import QueryInterpreter


class DecisionPlugin(BasePlugin):

    ID = 'decision'
    NAME = 'Decision'
    DESCRIPTION = 'Decision data using provided result'
    TYPE = 'decision'
    DEPENDENCIES = []
    VERSION = '1.0.0'
    MODULE = 'playbook.decision.Decision'
    ENABLED = True
    Exceptions = []
    playbookCache = {}
    DecisionToStep = {}

    def __init__(self, plugin_administrator, config=None):
        super().__init__(plugin_administrator, config=config, plugin_path=__file__)
        self.config = config
        self.logger = get_logger()
        self.playbookCache = {}
        self.DecisionToStep = {}

    def process_task(self, task):
        if task['cmd'] == 'addPlaybookStep':
            # self.logger.debug(json.dumps(task))

            self._add_playbook_step(task['data'])
            # start up new worker when new task arrives.

            if not task['data']['id'] in self.playbookCache:
                self.playbookCache[task['data']['id']] = {}

            self.playbookCache[task['data']['id']][task['data']['step']['id']] = {
                'config':  task['data']['step']
            }

            # for each next step...
            for next_step in task['data']['step']['next']:
                nx = self.get_step_by_id(task['data']['id'], next_step)
                dec = nx['decision']
                step = task['data']['id'] + ':' + nx['id']
                if not step in self.DecisionToStep:
                    self.DecisionToStep[step] = {"yes": [], "no": []}

                self.DecisionToStep[step][dec].append(nx['id'])

        else:
            # do the work
            # use return_value to make the decision of which step(s) go next

            task['route'] = 'publish'

            # this part depends
            step = self.get_step_by_id(
                task['data']['playbookId'], task['data']['step'])
            for next_step in step['next']:
                step = task['data']['playbookId'] + ':' + next_step

                if 'return_value' in task['data']['data'] and task['data']['data']['return_value'] == True:
                    task['data']['step'] = self.DecisionToStep[step]["yes"]
                    if len(task['data']['step']) > 0:
                        #self.logger.debug("DECISION OUTBOUND YES TASK")
                        # self.logger.debug(task)
                        self.outgoing_queue.put(task)
                    # else this goes to /dev/null :)
                elif 'return_value' in task['data']['data'] and task['data']['data']['return_value'] == False:
                    task['data']['step'] = self.DecisionToStep[step]["no"]
                    if len(task['data']['step']) > 0:
                        #self.logger.debug("DECISION OUTBOUND NO TASK")
                        # self.logger.debug(task)
                        self.outgoing_queue.put(task)
                    # else this goes to /dev/null :)
                else:
                    raise Exception(
                        "Decision task does not havea areturn value, task: %s" % json.dumps(task))

    def add_exception(self, msg):
        self.Exceptions.append(msg)

    def check_exceptions(self):
        # if exceptiosn found, then log out
        return self.Exceptions

    def shutdown(self):
        # stop all on-going workers here
        self.logger.debug('Decision plugin is now shutting down.')
        # super().shutdown()
        self.logger.debug('Decision shutdown complete.')
