
from shinsapp import SHINSApp
from util.shinsLogger import logger
from alignment.allineamento import Align_the_coronagraph as aly
from alignment.utils import read_image
from util import variables as uvars
from util import functions as ufun
from util import exception
from time import sleep
import easysnmp
import numpy as np
from astropy.io import fits

class SHARKNIR_gen_base(SHINSApp):
    
    @exception.handler_for_run
    def run(self, ins_s=None, det_s=None, tel_s=None, rtc_s=None, **kwargs):
        '''
        Setup + Image optimizing time
        '''
        logger.info(__name__)
        obsController = self.obsController
        self.status = uvars.EXIT_SUCCESS

        tpl_id = str(kwargs["TPLID"]) if (kwargs and "TPLID" in kwargs) else None

        fitsDir = uvars.fitsDir + obsController.getCurrentDataDirectory() +'/'

        ###################################
        # Starting instrument setup, if any
        if ins_s:
            
            #########################
            # SHOW INSTRUMENT SETUP #
            #########################
            
            logger.info("Instrument Setup")
            for element, value in ins_s.items():
                logger.debug("{:>22} : {:<22}".format(element, str(value)))
        
                
            ##########################
            # START INSTRUMENT SETUP #
            ##########################
            if self.paragraph("START INSTRUMENT SETUP"): 
                        
                logger.info("Instrument setup starting")
                async = obsController.begin_setupInstrument(ins_s)
                logger.info("Instrument setup started")
                self.status = uvars.EXIT_FAILURE

                
        #################################
        # Starting detector setup, is any
        if det_s:
            
            ###############################################
            # Evaluating if scientific or technical image #
            ###############################################

            ngmin = uvars.Sci_Image_NGMIN if (tpl_id=="SHARKNIR_ci_obs" or tpl_id=="SHARKNIR_di_obs") else uvars.Default_NGMIN
            logger.debug("Scientific Image: Calculating Scicam parameters with ngmin = {}".format(ngmin))
            ngmax = kwargs["ngmax"] if (type(kwargs)==dict and "ngmax" in kwargs) else None
            if ngmax:
                logger.warning("Technical Image: Calculating Scicam parameters with ngmax = {}".format(ngmax))

            #####################################
            # CONVERTING DIT INTO SCICAM PARAMS #
            #####################################
            
            if "DIT" in det_s:
                logger.debug("DIT : "+det_s["DIT"]+" specified. Calculating ramp params from this value")
                ramp_s = ufun.calc_ramp_settings(det_s["DIT"], det_s["READOUT"], ngmax=ngmax , ngmin=ngmin)
                det_s.update(ramp_s)
                           
            #######################
            # SHOW DETECTOR SETUP #
            #######################
            
            logger.info("Detector Setup")
            for element, value in det_s.items():
                logger.debug("{:>22} : {:<22}".format(element, str(value)))
                        
            #####################
            # START SASHA SETUP #
            #####################
            if self.paragraph("START SASHA SETUP"): 
                        
                logger.info("Setting up SASHA ...")
                asyncResSashaSetup = obsController.begin_sashaSetup(det_s)
                logger.info("Setting up SASHA ... DONE")                            


        ##################################
        # Waiting instrument setup, is any
        if ins_s:
                
            #########################
            # WAIT INSTRUMENT SETUP #
            #########################
            if self.paragraph("WAIT INSTRUMENT SETUP"): 
                
                logger.info("Waiting Instrument setup to complete...")
                self.status = obsController.end_setupInstrument(async)
                ufun.error_handler(self.status, "setupInstrument")
                logger.info("Instrument setup... DONE")        
                

        #############################################
        # Waiting detector setup, is any, then expose
        if det_s:
                
            ####################
            # WAIT SASHA SETUP #
            ####################
            if self.paragraph("WAIT SASHA SETUP"): 
                
                logger.info("Waiting SASHA setup ...")
                self.status = obsController.end_sashaSetup(asyncResSashaSetup)
                logger.info("Waiting SASHA setup ... DONE")
                        

                
            #############################################
            # Take the image if kwargs["expose"] is not set to False
            if "expose" in kwargs and kwargs["expose"] == False:
                pass
            else:    
                
                ##################
                # EXPOSING SASHA #
                ##################
                if self.paragraph("EXPOSING SASHA"): 
                    
                    logger.info("Waiting camera exposure to complete ...")
                    self.status, self.filenames = obsController.sashaExpose()
                    logger.info("Waiting camera exposure to complete ... DONE")
                    logger.info("FITS files are "+str(self.filenames))
                        
                    
                #####################
                # SHOW IMAGES STATS #
                #####################
                if self.paragraph("IMAGE(S) STATS"): 
                    
                    saly = aly(camera='HAWAII H-2RG')
                    saly.detector.setCrop(3)
                    im_arr = []
                    
                    for image in self.filenames:
                        fitsDir = uvars.fitsDir + obsController.getCurrentDataDirectory() +'/'
                        data = fits.getdata(fitsDir+image)
                        # img_ = read_image(fitsDir+image, saly.detector)
                        # im_arr.append(img_)

                        logger.debug("-------------------------")
                        logger.debug("Image     : {}".format(image))
                        # logger.debug("Tot Flux  : {}".format(np.sum(data)))
                        logger.debug("Mean      : {}".format(np.mean(data)))
                        logger.debug("Median    : {}".format(np.median(data)))
                        logger.debug("Stddev    : {}".format(np.std(data)))
                        logger.debug("Zeroes    : {}".format(np.count_nonzero(data==0)))

                    # logger.debug("Making mean of {} images".format(len(im_arr)))
                    # meaned = np.mean(np.asarray(im_arr), 0)
                    # print("kwargs[TPLID] : {}".format(str(kwargs["TPLID"])))
                    # print("kwargs[OB] : {}".format(str(kwargs["OB"])))
                    
                    
                    #     logger.debug("Processing image ... ")
                    #     saly.PSFNoCoro.LoadImage(meaned)
                    #     saly.PSFNoCoro.removeHotPixels(verbose=True)
                    #     saly.PSFNoCoro.Center(model='Gaussian2D', box=20, display=False)
                    #     saly.PSFNoCoro.calculate_bkg()
                        
                    #     self.tpl_output = {
                    #         uvars.tpl_output_names["sasha_flux"] : np.round(saly.PSFNoCoro.flux, 2),
                    #         uvars.tpl_output_names["sasha_max"]  : np.max(saly.PSFNoCoro.image),
                    #         uvars.tpl_output_names["sasha_min"]  : np.min(saly.PSFNoCoro.image)
                    #     }

                    if "NDIT" in det_s:
                        if int(det_s["NDIT"]) != len(self.filenames):
                            msg = "FITS requested: {}, FITS saved: {} !".format(det_s["NDIT"], len(self.filenames))
                            logger.warning(msg)
                            ufun.error_handler(self.status, "sashaExpose")
                        
                    if self.status:
                        ufun.error_handler(self.status, "sashaExpose")

                    
