from abc import ABC

import tornado.ioloop
import tornado.web
import tornado.escape
import collections
import json
import pyansys
import os
import sqlite3 as lite
import sys

import gfk_plate
import time

import logging

from ini_logger import *

# log_dir = r'/var/log/server'
# ini_logger(log_dir)

inputs = [
    {'type': "e11", 'value': [42.5E9]},
    {'type': "e22", 'value': [11E9]},
    {'type': "e33", 'value': [11E9]},
    {'type': "pr12", 'value': [0.28]},
    {'type': "pr13", 'value': [0.28]},
    {'type': "pr23", 'value': [0.28]},
    {'type': "g12", 'value': [4.2E9]},
    {'type': "g13", 'value': [4.2E9]},
    {'type': "g23", 'value': [2.56E9]},
    {'type': "dens", 'value': [1950]},
    {'type': "alp11", 'value': [5.7E-6]},
    {'type': "alp22", 'value': [45E-6]},
    {'type': "alp33", 'value': [45E-6]},
    {'type': "k11", 'value': [0.72E3]},
    {'type': "k22", 'value': [0.5E3]},
    {'type': "k33", 'value': [0.5E3]},
    {'type': "bet11", 'value': [0E-3]},
    {'type': "bet22", 'value': [4E-3]},
    {'type': "bet33", 'value': [4E-3]},
    {'type': "d11", 'value': [4.4E-3]},
    {'type': "d22", 'value': [3.1E-3]},
    {'type': "d33", 'value': [3.1E-3]},
    {'type': "angles", 'value': [90, 0, 0, 0, 0, 0]},
    {'type': "outer_diameter", 'value': [0.250]},
    {'type': "inner_diameter", 'value': [0.050]},
    {'type': "thickness", 'value': [0.005]},
    {'type': "omega", 'value': [1]}
]

outputs = [
    {'type': "S1max", 'value':  [0]},
    {'type': "S2max", 'value':  [1]},
    {'type': "Srmax", 'value':  [2]},
    {'type': "Stmax", 'value':  [3]},
    {'type': "f1", 'value':     [1]},
    {'type': "f2", 'value':     [2]},
    {'type': "f3", 'value':     [3]}
]

status = {
    "status": "ready"
}


def update():
    materials = []
    for i in range(0, len(inputs[0]['value'])):
        material = {}
        for j in range(0, len(inputs) - 5):
            material[inputs[j]['type']] = inputs[j]['value'][i]
        materials.append(material)
    success = False
    while not success:
        try:
            outputs[0]['value'][0], outputs[1]['value'][0], outputs[2]['value'][0], outputs[3]['value'][
                0], outputs[4]['value'][0], outputs[5]['value'][0], outputs[6]['value'][0] = gfk_plate.sim_rotor(
                materials, inputs[len(inputs) - 5]['value'], inputs[len(inputs) - 4]['value'][0],  inputs[len(inputs) - 3]['value'][0],  inputs[len(inputs) - 2]['value'][0],  inputs[len(inputs) - 1]['value'][0])
            success = True
        except PermissionError:
            print("Catch Error")
            # time.sleep(3)
            success = False


class MainHandler(tornado.web.RequestHandler, ABC):
    def prepare(self):
        self.set_header("Content-Type", "application/json")
        if self.request.headers.get('Content-Type') == 'application/json':
            print(self.request.body)
            self.json_args = json.loads(self.request.body.decode('utf-8'))
        else:
            self.json_args = None

    def get(self, param):
        print("INFO: GET /" + param)
        if param == "inputs":
            self.write(json.dumps(inputs))
        elif param == "outputs":
            self.write(json.dumps(outputs))
        elif param == "status":
            self.write(json.dumps(status))
        elif param == "stop":
            instance = tornado.ioloop.IOLoop.instance()
            instance.add_callback(instance.stop)
        else:
            self.write("Error: GET /" + param)
            print("Error: GET /" + param)

    def post(self, param):
        if param == "update":
            status["status"] = "updating"
            if self.json_args is not None:
                # print("INFO: GET /" + param + "with body: " + self.json_args.dump())
                counter = 0
                for entity in self.json_args:
                    inputs[counter]['value'] = entity['value']
                    # print("INFO: update " + str(entity['value'][0]))
                    counter = counter + 1
            update()
            self.write(json.dumps(outputs))
            status["status"] = "ready"
        else:
            self.write("Error: POST /" + param)
            print("Error: POST /" + param)


def make_app():
    return tornado.web.Application([
        (r"/(.*)", MainHandler),
    ])


if __name__ == "__main__":
    app = make_app()
    if len(sys.argv) == 1:
        app.listen(int(8888))
    else:
        app.listen(int(sys.argv[1]))

    tornado.ioloop.IOLoop.current().start()
