#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import datetime

import numpy as np
from tpl.shinsapp import SHINSApp
from util import functions as ufun

from util.mini_os import obsController


class DevicesObject(object):
    def __init__(self):
        self.obsController = obsController
        self.json_state = {}
        self.soul_deltas = [-999,-999] 
        
    def readall(self):
        json_string = "{}"
        try:
            status, json_string = self.obsController.getJsonStatus()
            if ', , ' in json_string:
                index = json_string.index(', ,')
                json_elements = len(json_string.split("},"))
                json_string = ufun.filterString(main_string = json_string, substring = ", , ", new_substring = ", ")
                print(str(datetime.datetime.now())+"Received Json had {} elements. Missing element at char {} : '{}'".format(json_elements,index, json_string[index-10:index+20]))
        except Exception as e: #CommunicatorDestroyedException: or ConnectionLostException:
            print(str(datetime.datetime.now())+" : ERROR ______GETTING JSON________ Found the following exception: {}".format(e))
                        
        try:
            json_dict = json.loads(json_string)

            drot_pos_deg = ufun.drot_step2deg(json_dict["DROT_PosAng"]["encoder"])
            json_dict["DROT_PosAng"]["encoder"] = np.round(drot_pos_deg,3)
            json_dict["soul-deltas"] = self.soul_deltas
            self.json_state = json_dict
            return json_dict
        except Exception as e:
            print(str(datetime.datetime.now())+" : ERROR _________Void Json exception, no DROT_PosAng specified. Exception is: {}".format(e))
            self.json_state = json_dict
            return json_dict

    def read(self, dev):
        outDict = self.readall()
        return outDict[dev]

    def move(self, ins_s):

        status = self.obsController.setupInstrument(ins_s)

        return ins_s

    def absolute(self, ins_s):
        status = self.obsController.setupInstrumentAbsolutePosition(ins_s)
        return status

    def relative(self, ins_s):
        status = self.obsController.setupInstrumentRelativePosition(ins_s)
        return status

    def home(self, ins_s):

        lamps_s = dict((k, "OFF") for k in  ["CAL_FF_LAMP", "CAL_FIBER_FOCUS_LAMP", "CAL_FIBER_DEFOCUS_LAMP"] if k in ins_s)
        if lamps_s:
            self.obsController.setupInstrument(lamp_s)

        status = self.obsController.initMotion(ins_s.keys())
        status = self.obsController.initCalibUnit([k for k in ["CAL_FILTER_DEP", "CAL_MIRROR_DEP", "CAL_FIBER_DEP"] if k in ins_s])

        return status

    def stop(self, ins_s):
        status = self.obsController.stopMotion(ins_s.keys())
        return status

    def abort(self):
        status = self.mini_os.abort()
        return status

