
from shinsapp import SHINSApp
from util.shinsLogger import logger
from util import functions as ufun
from util import variables as uvars
from util import exception
from time import sleep

class SHARKNIR_gen_init_and_park(SHINSApp):

    @exception.handler_for_run
    def run(self, ins_s=None, det_s=None, tel_s=None, rtc_s=None, **kwargs):
        '''Init or park devices'''
        logger.info(__name__)
        obsController = self.obsController
        self.status = uvars.EXIT_SUCCESS

        operation = None 
        ###########################################
        # ELECTROVALVE AND TEMPERATURE MANAGEMENT #
        ###########################################
        if(kwargs):
            if(kwargs["TPLID"]):
                if("init" in str(kwargs["TPLID"])):

                    operation = "init"
                    if self.paragraph("MANAGE ELECTROVALVE"):
                        logger.info("Turning Electrovalve Outlet ON...")
                        status = obsController.setupInstrument({"ELECTROVALVE": "ON"})
                        sleep(1)
                        logger.info(status)
                        logger.info("Turning Electrovalve Outlet ON... DONE")
                        
                    if self.paragraph("SET TECCAM TEMPERATURE"):
                        logger.info("Setting temperature to -15...")
                        obsController.RTCTTSendCameraCommand("set temperatures sensor -15")
                        logger.info("Setting temperature to -15...DONE")
                                                             
                elif("park" in str(kwargs["TPLID"])):

                    operation = "park"
                    if self.paragraph("MANAGE ELECTROVALVE"):
                        logger.info("Turning Electrovalve Outlet OFF...")
                        status = obsController.setupInstrument({ "ELECTROVALVE": "OFF"})
                        sleep(1)
                        logger.info(status)
                        logger.info("Turning Electrovalve Outlet OFF... DONE")

                    if self.paragraph("SET TECCAM TEMPERATURE"):
                        logger.info("Setting temperature to 20...")
                        obsController.RTCTTSendCameraCommand("set temperatures sensor 20")
                        logger.info("Setting temperature to 20...DONE")
                        
                else:
                    logger.warning("no init nor park")
            else:
                logger.warning("no TPLID in kwargs")
        else:
            logger.warning("no kwargs at all... setting temperature by instant mesurement")
                
            ##########################
            # SET TECCAM TEMPERATURE #
            ##########################
            if self.paragraph("SET TECCAM TEMPERATURE"):
                
                command = "temperatures sensor"
                temp_string = obsController.RTCTTSendCameraCommand(command)
                try: # T(C) sensor: -14.98
                    temp = float(temp_string[1].split(":")[1])
                    if temp > -5:
                        logger.debug("Setting temperature to -15")
                        obsController.RTCTTSendCameraCommand("set temperatures sensor -15")
                    else:
                        logger.debug("Setting temperature to 20")
                        obsController.RTCTTSendCameraCommand("set temperatures sensor 20")
                except (IndexError,TypeError) as e:
                    logger.error("Unable to get sensor temperature: won't set anything.")

        if operation == "park":
            ###########################################
            # OPENING INTERNAL TT LOOP and FLATTEN DM #
            ###########################################
            if self.paragraph("OPEN INTERNAL TT LOOP"):
                logger.info("Opening internal TT loop ...")
                obsController.RTCTTOpenLoop()
                logger.info("Opening internal TT loop ... DONE")
            if self.paragraph("FLATTEN INTERNAL DM"):
                try:
                    mode = ufun.get_status_by_name(self.obsController, ['rtc_dm_mode'])[0]
                    logger.info("RTC is in {} mode, flattening DM ...".format(mode))
                    if mode == "ZONAL":
                        print("detected ZONAL")
                        modes = [0] * 99
                        status = obsController.RTCTTModeUpload(modes, absolute=True)
                    elif mode=="MODAL":
                        modes = [0] * 39
                        status = obsController.RTCTTModeUpload(modes, absolute=True)
                    obsController.setContext({"NCPA_FILE":"zeri.txt"})
                    logger.info("Flattening DM ... DONE")
                except Exception as e:
                    print(e)
                    logger.error("Unable to flatten the DM")

        ######################
        # PLACE ADCs to ZERO #
        ######################
        if self.paragraph("PLACE ADCs TO ZERO"):
            
            logger.debug("start adcs")
            status = obsController.setupInstrument({ "ADC_Mode": "OFF"})
            sleep(1)
            logger.debug(status)
            status = obsController.setupInstrument({ "ADC1_PosAng": "0.0",  "ADC2_PosAng": "0.0"})
            logger.debug(status)
            logger.debug("end adcs")

        if operation == "init":

            ################################################
            # CHECK AUTHORIZED INSTRUMENT ON LBT LEFT SIDE #
            ################################################
            if self.paragraph("Check Authorized Instrument at LBT"):
                left_ins, right_ins = ufun.checkLBTAuthorization(obsController)
                if left_ins and "SHARK" in left_ins:
                    logger.info("SHARK-NIR is authorized!")
                else:
                    logger.warning("SHARK-NIR is NOT authorized!")
            ###########################
            # INIT ALMOST ALL DEVICES #
            ###########################
            # if self.paragraph("START INIT DEVICES"):
            
            #     logger.debug("start mot")
            #     async_mot = obsController.begin_initMotion([
            #         "INBEAM_DEP",
            #         "INBEAM_TT",
            #         "SHUTTER",
            #         "APODIZER_W",
            #         "CORO_SLIT_W",
            #         "LYOT_GRISM_W",
            #         "ND_FILT_W",
            #         "SCI_FILT_W1",
            #         "SCI_FILT_W2",
            #         "PUPIL_LENS_DEP",
            #         "DB_FILT_W",
            #         # "ADC1",
            #         # "ADC2",
            #     ])
            
            #     logger.debug("start cal")
            #     async_cal = obsController.begin_initCalibUnit(["CAL_FILTER_DEP",
            #                                                    "CAL_MIRROR_DEP",
            #                                                    "CAL_FIBER_DEP"])
            
            # ###########################
            # # WAIT ALMOST ALL DEVICES #
            # ###########################
            # if self.paragraph("WAIT INIT DEVICES"):
            
            #     logger.debug("end cal")
            #     status = obsController.end_initCalibUnit(async_cal)
            #     logger.debug(status)
            #     status = obsController.end_initMotion(async_mot)
            #     logger.debug(status)
            
            #########################
            # INIT CALIBRATION UNIT #
            #########################
            if self.paragraph("Init Calibration Unit"): 
                logger.debug("start cal")
                async_cal = obsController.initCalibUnit(["CAL_FILTER_DEP",
                                                         "CAL_MIRROR_DEP",
                                                         "CAL_FIBER_DEP"])
                logger.debug("Calibration unit initialization ... DONE")

            #########################
            # INIT CALIBRATION UNIT #
            #########################
            if self.paragraph("Init Motion Unit"): 
                logger.debug("start mot")
                obsController.initMotion([
                    "INBEAM_DEP",
                    "INBEAM_TT",
                    "SHUTTER",
                    "APODIZER_W",
                    "CORO_SLIT_W",
                    "LYOT_GRISM_W",
                    "ND_FILT_W",
                    "SCI_FILT_W1",
                    "SCI_FILT_W2",
                    "PUPIL_LENS_DEP",
                    "DB_FILT_W",
                    # "ADC1",
                    # "ADC2",
                ])
                
                logger.debug("Motion unit initialization ... DONE")

        #############################################
        # START AND WAIT INSTRUMENT AND SASHA SETUP #
        #############################################
        if self.paragraph("Instrument Setup"):
            
            logger.info("Instrument Setup")
            for element, value in ins_s.items():
                logger.debug("{:>22} : {:<22}".format(element, str(value)))
            obsController.setupInstrument(ins_s)
            logger.info("Instrument Setup... DONE")

        self.status, _ = obsController.RTCTTSendCameraCommand("temperatures")
