from ipykernel.kernelbase import Kernel

import requests
import argparse
import sys
import json

import vadalog_runner
from vadalog_runner import VadalogRunner

from result_analyser import ResultAnalyser

from result_wrappers import ExecutionResultsWrapper, ExecutionExceptionWrapper

GLOBAL_PARAMS = {
    "config": None,
    "vadalog_program_logger": None
}

# example: https://github.com/takluyver/bash_kernel/blob/master/bash_kernel/kernel.py
class VadalogKernel(Kernel):
    # http://jupyter-client.readthedocs.io/en/stable/wrapperkernels.html

    # ‘Implementation’ refers to the kernel (e.g. IPython), rather than the language (e.g. Python)
    implementation = 'IPython'
    implementation_version = '1.1.0'
    #language = 'vadalog'
    language = 'vadalog'
    language_version = '0.0.1'
    language_info = {'name': 'vadalog', 'mimetype': 'text/x-vadalog', 'file_extension': '.vada', 'codemirror_mode': 'vadalog'}

    help_links = [{'text': 'Vadalog Help', 'url': "http://www.prometheux.co.uk"}]
    # The ‘banner’ is displayed to the user in console UIs before the first prompt.
    banner = "Vadalog Kernel"

    def do_execute(self, code, silent,
                   store_history=True,
                   user_expressions=None,
                   allow_stdin=False):

        # jupyter-client.readthedocs.io/en/stable/messaging.html#execution-results
        OK = {'status': 'ok',
              'execution_count': self.execution_count,
              'payload': [], # this parameter is deprecated
              # Results for the user_expressions
              'user_expressions': {"test1":"test2"}}

        if not silent:
            try:
                results_json = VadalogRunner(GLOBAL_PARAMS["config"]["vadalog_endpoint"]).run(code)
            except Exception as ex:
                self._send_error("Error executing Vadalog program. {0}".format(ex))
                return OK

            analysis_res = ResultAnalyser(results_json).analyse()
            if analysis_res["status"] != "SUCCESS":
                self._send_error( analysis_res["error_msg"] )
                if GLOBAL_PARAMS["vadalog_program_logger"]:
                    GLOBAL_PARAMS["vadalog_program_logger"].log_query("internal", code, "error")
                return OK

            mime = None
            results_send = None
            response = results_json["response"]

            try:
                # Only handle RUN_PROGRAM_MODE - simplified execution
                mime = "text/html"
                results_send = ExecutionResultsWrapper(response).to_html_string()
            except Exception as e:
                #self._send_error("Error: ResponseParsing. Exception: {0}. Server response: {1}".format(str(e), str(results_json)))
                self._send_error(response["errorMessage"])
                return OK

            if results_send is None:
                self._send_error("No result.")
                return OK
            else:
                if GLOBAL_PARAMS["vadalog_program_logger"]:
                    GLOBAL_PARAMS["vadalog_program_logger"].log_query("internal", code, "ok")
                
                self.send_response(self.iopub_socket, 'display_data', {"data": { mime: results_send}, "metadata": {}})
        return OK

    def _send_error(self, error_message):
        self.send_response(self.iopub_socket,
                           'display_data',
                           {"data": {
                               "text/html": ExecutionExceptionWrapper(error_message).to_html_string()},
                           "metadata": {}})

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--config', help="Configuration file, optional")
    ap.add_argument('-f', help="Jupyter parameter")
    args = ap.parse_args()
    if not args.config or not args.config.strip():
        print ("Specify the config parameter")
        sys.exit(0)
    with open(args.config) as json_data_file:
        GLOBAL_PARAMS["config"] = json.load(json_data_file)

    if GLOBAL_PARAMS["config"].get("query_logging_enabled", False):
        from query_logger import QueryLogger
        GLOBAL_PARAMS["vadalog_program_logger"] = QueryLogger(GLOBAL_PARAMS["config"]["vadalog_program_logfile"])

    from ipykernel.kernelapp import IPKernelApp
    IPKernelApp.launch_instance(kernel_class=VadalogKernel)


if __name__ == '__main__':
    main()
