<reponame>roholazandie/ParlAI
import logging
import re

from parlai.agents.programr.brain import Brain
# from parlai.agents.programr.utils.logging.ylogger import YLogger
import parlai.utils.logging as logging
from parlai.agents.programr.clients.events.client import EventBotClient
from parlai.agents.programr.clients.events.console.config import ConsoleConfiguration

from parlai.agents.programr.aiml_manager import AIMLManager


class ConsoleBotClient(EventBotClient):

    def __init__(self, argument_parser=None):
        self.running = False
        self.brain = None
        self.aiml_manager = AIMLManager.get_instance()
        super().__init__(argument_parser)

    def get_description(self):
        return 'ProgramR AIML2.0 Console Client'

    def get_client_configuration(self):
        return ConsoleConfiguration()

    def add_client_arguments(self, parser=None):
        return

    def parse_args(self, arguments, parsed_args):
        return

    def get_question(self, input_func=input):
        try:
            ask = "%s " % self.get_client_configuration().prompt
            return input_func(ask)
        except Exception as excep:
            # YLogger.debug(self, "Exception caught in get_question !", excep)
            logging.debug(f"Exception caught in get_question ! {excep}")

    def get_user_preferences(self):
        user_preferences_dict = {}
        user_preferences_dict.pop("_id", "No Key found")
        user_preferences_dict.pop("_rev", "No Key found")
        user_preferences_dict["topic"] = "*"

        return user_preferences_dict

    def get_brain(self, userid):
        brain = Brain(userid)
        return brain

    def display_startup_messages(self, ):
        #self.process_response(self.bot.get_version_string())
        initial_question = self.bot.get_initial_question()
        self._renderer.render(initial_question)

    def process_question(self, client_context, question):
        # Returns a response
        return client_context.bot.ask_question(client_context, question, responselogger=self)

    def process_question_with_options(self, question):
        return self.bot.ask_question(question, responselogger=self)

    def render_response(self, response):
        # Calls the renderer which handles RCS context, and then calls back to the client to show response
        self._renderer.render(response)

    def process_response(self, response):
        response = self.remove_oob(response)
        print(response)

    def remove_oob(self, response):
        return re.sub('<oob><robot></robot></oob>', '', response)

    def process_sentiment(self, client_context, question):
        # Calculating and saving sentiment
        sentiment_value, sentiment_distribution = client_context.brain.nlp.sentiment_analysis.get_sentence_sentiment(
            question)
        numerical_sentiment = client_context.brain.nlp.sentiment_analysis.expected_sentiment_value(
            sentiment_distribution)

        client_context.bot.sentiment.append_sentiment(numerical_sentiment)
        client_context.bot.sentiment.append_sentiment_distribution(sentiment_distribution)

        # print("Sentiment: {}".format(sentiment_value))
        # print("Sentiment for current sentence: {}".format(numerical_sentiment))
        # print("Sentiment Distribution: {}".format(sentiment_distribution))
        # print("Sentiment list: {}".format(client_context.bot.sentiment._sentiment_values))
        # print("Rolling Sentiment: {}".format(client_context.bot.sentiment._rolling_sentiment))

        return client_context, client_context.bot.sentiment._threshold_reached

    def process_question_answer(self, client_context):
        question = self.get_question(client_context)
        response = self.process_question(client_context, question)
        self.render_response(client_context, response)

    def process_question_answer_with_options(self, ):
        try:
            question = self.get_question()
            response, options = self.process_question_with_options(question)

            # client_context, threshold_reached = self.process_sentiment(client_context, question)
            # if threshold_reached:
            #     response, options = client_context.bot.ask_question_with_options(client_context, "XTHRESHOLD REACHED")
            # client_context.bot.save_conversation(client_context)

            self.render_response(response)
        except Exception as ex:
            # YLogger.exception(self, "Exception caught in process_question_answer_with_options !", ex)
            logging.error(f"Exception caught in process_question_answer_with_options ! {ex}")

    def wait_and_answer(self, ):
        running = True
        try:
            self.process_question_answer_with_options()
        except KeyboardInterrupt as keye:
            running = False
            exit_response = self.bot.dialog.get_exit_response()
            self._renderer.render(exit_response)
        except Exception as excep:
            # YLogger.exception(self, "Oops something bad happened !", excep)
            logging.exception(f"Oops something bad happened ! {excep}")
        return running

    def prior_to_run_loop(self):
        user_preferences = self.get_user_preferences()
        self.brain = self.get_brain("iddd")
        self.brain.set_user_preferences(user_preferences)
        #self.display_startup_messages()

    def run(self):
        # YLogger.info(self, "Entering conversation loop...")
        logging.info("Entering conversation loop...")

        self.prior_to_run_loop()

        self.run_loop()


if __name__ == '__main__':
    def run():
        print("Loading, please wait...")
        console_app = ConsoleBotClient()
        console_app.run()


    run()
