import sys
sys.path.append("wrappers")
from modelverse import *
import random, re, json, uuid
from pprint import pprint
from multiprocessing import Process, Pipe, freeze_support

sys.path.append('services/DEVS/pypdevs/src')
sys.path.append('services/DEVS/models')

from simulator import Controller

import threading, time

def pypdevs_service(port):
    code = service_get(port)
    model_name = str(uuid.uuid4()).replace("-", "")

    with open("services/DEVS/models/" + model_name + ".py", 'w') as f:
        f.write(code)

    Root = getattr(__import__(model_name), "Root")
    controller = Controller(Root())

    def inputter():
        print("Waiting for input...")
        while 1:
            try:
                input = service_get(port)
                print('raw input = %s' % input)
                params = json.loads(input)
                print('json parsed = %s' % params)
                if not isinstance(params, list):
                    params = [params]
                print("Sending input to simulator: %s" % params)
                if (len(params) > 1):
                    controller.addInput(Event(params[0], "request", params[1:]))
                else:
                    controller.addInput(Event(params[0], "request", []))
            except:
                import traceback
                traceback.print_exc()

    input_thread = threading.Thread(target=inputter)
    input_thread.daemon = True
    input_thread.start()

    output_listener = controller.addOutputListener(["reply"])

    def outputter():
        print("Waiting for output...")
        while 1:
            output_val = output_listener.fetch(-1)
            print("Got output from simulator: %s" % output_val)
            service_set(port, json.dumps({"name": output_val.getName(), "port": output_val.getPort(), "params": output_val.getParameters()}))

    output_thread = threading.Thread(target=outputter)
    output_thread.daemon = True
    output_thread.start()

    controller.start()

try:
    init(sys.argv[1])
    login("pypdevs_service", "my_password")

    service_register("pypdevs_simulator", pypdevs_service)

    try:
        while True:
            # Stay active, as we shouldn't exit while the service is running!
            time.sleep(1)
    finally:
        service_stop()
except KeyboardInterrupt:
    pass
