import traceback
from logging import getLogger

from chatterbot.conversation import Statement
from flask import jsonify, request, make_response
from flask_restful import Resource, reqparse

from common.request import InvalidTokenException
from common import marshall
from .logic.requests import Request

log = getLogger(__name__)

INVALID_TOKEN_MESSAGE = "Couldn't query Waldur because of invalid or missing token, please send valid token"
MISSING_QUERY_MESSAGE = "Parameter 'query' missing from request"
MISSING_TEACH_MESSAGE = "Request needs parameters 'statement' and 'in_request_to'"
SYSTEM_ERROR_MESSAGE  = "Internal system error."


class Query(Resource):
    __name__ = ''

    def __init__(self, chatbot):
        log.info("Initializing Query class")
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('query')
        self.parser.add_argument('token')
        self.chatbot = chatbot

    def post(self):
        try:
            log.info("IN:  " + str(request.json))
            args = self.parser.parse_args()
            query = args['query']
            token = args['token']

            if query is not None:
                response = self.get_response(query, token)
                code = 200
            else:
                response = marshall.text(MISSING_QUERY_MESSAGE)
                code = 400

        except InvalidTokenException as e:
            log.info("InvalidTokenException: " + str(e))
            response = marshall.text(INVALID_TOKEN_MESSAGE)
            code = 401
        except Exception:
            for line in traceback.format_exc().split("\n"): log.error(line)
            response = marshall.text(SYSTEM_ERROR_MESSAGE)
            code = 500

        log.info("OUT: " + str(response) + " code: " + str(code))
        return make_response(jsonify(response), code)

    def get_response(self, query, token):
        bot_response = str(self.chatbot.get_response(query))

        if bot_response.startswith("REQUEST"):
            req = Request\
                .from_string(bot_response)\
                .set_token(token)\
                .set_original(query)

            response = req.process()

            if req.output == 'text':
                return marshall.text(response)
            elif req.output == 'graph':
                return marshall.graph(response)
        else:
            return bot_response


class Teach(Resource):

    def __init__(self, chatbot):
        log.info("Initializing TeachBot class")
        self.parser = reqparse.RequestParser()
        self.parser.add_argument('statement')
        self.parser.add_argument('in_response_to')
        self.chatbot = chatbot

    def post(self):
        try:
            log.info("IN:  " + str(request.json))
            args = self.parser.parse_args()
            statement = args['statement']
            in_response_to = args['in_response_to']

            if statement is not None and in_response_to is not None:
                self.chatbot.learn_response(Statement(statement), Statement(in_response_to))
                response = marshall.text("ok")
                code = 200
            else:
                response = marshall.text(MISSING_TEACH_MESSAGE)
                code = 400

        except Exception:
            for line in traceback.format_exc().split("\n"): log.error(line)
            response = marshall.text(SYSTEM_ERROR_MESSAGE)
            code = 500

        log.info("OUT: " + str(response) + " code: " + str(code))
        return make_response(jsonify(response), code)

@@ -2200,16 +2200,68 @@
 'text':%0A
+                print(str(marshall.text(response)))%0A
         
@@ -2420,16 +2420,30 @@
  return 
+marshall.text(
 bot_resp
@@ -2446,16 +2446,17 @@
 response
+)
 %0A%0A%0Aclass

Am dumb