#! /usr/bin/env python3
# -*- coding: iso-8859-15 -*-

import matplotlib as mpl
mpl.use('Agg') # necessary to be able to generate the reports even without X server

import cProfile
import pstats
import glob
import os
import time
import argparse

import gravi_trend as gt
from gravi_reduce import gravi_esorex as ge
from gravi_reduce import (log, ERROR, WARNING, NOTICE, set_verbose_type)
log = log.Log().log

usage = """
description:
  Run the calibration recipe on all data in the current directoty
  It output the results in calibrated/ and produce some PDF plots.
"""
examples = """
examples:
  run_gravi_trend.py --loop=TRUE
  run_gravi_trend.py

""" 

dtime = 60*3

#
# Implement options
#

parser = argparse.ArgumentParser(description=usage, epilog=examples,formatter_class=argparse.RawDescriptionHelpFormatter)
TrueFalse = ['TRUE','FALSE']
TrueFalseOverwrite = ['TRUE','FALSE','OVERWRITE']

parser.add_argument("--loop", dest="loop",default='FALSE',choices=TrueFalse,
                  help="Run in loop every 10 seconds [FALSE]")

parser.add_argument("--load-data", dest="load_data",default='TRUE',choices=TrueFalse,
                  help="Load new files [TRUE]")

parser.add_argument("--tf", dest="tf",default='TRUE',choices=TrueFalseOverwrite,
                  help="Compute the TF [TRUE]")

parser.add_argument("--viscal", dest="viscal",default='OVERWRITE',choices=TrueFalseOverwrite,
                  help="Recalibrate visibilities [OVERWRITE]")

parser.add_argument("--commoncalib-dir", dest="commoncalibdir", default="../../common_calibration",
                  help="Add this directory in the search path for common"
                  "calibration files   [../../common_calibration]")

parser.add_argument("--calibrated-dir", dest="calibrateddir", default="calibrated/",
                  help="Directory for products [calibrated/]")

parser.add_argument("--plot-data", dest="plot_data",default='FALSE',choices=TrueFalse,
                  help="Plot data [FALSE]")


#
# esorex recipe options (minimal support)
#

options =[['gravity_viscal.force-calib',None],
          ['gravity_viscal.nsmooth-tfvis-sc',None],
          ['gravity_viscal.nsmooth-tfflux-sc',None],
          ['gravity_viscal.maxdeg-tfvis-sc',None],
          ['gravity_viscal.smoothing',None],
          ['gravity_viscal.separate-phase-calib',None],
          ['esorex.msg-level','info'],
          ['esorex.time','TRUE'],
          ['esorex.mem-check','TRUE'],
          ['esorex.recipe-dir',None]]

ge.implement_recipe_options (parser,options)

gt.plots.plot_defaults["directory"] = "./trends"

nfeed=1

if __name__ == "__main__":

    ##
    # Parse arguments
    argoptions = parser.parse_args()

    msg_level = vars(argoptions)['esorex.msg-level']
    if msg_level == 'error':
        set_verbose_type(ERROR)
    elif msg_level == 'warning':
        set_verbose_type(ERROR+WARNING)
    else:
        set_verbose_type(ERROR+WARNING+NOTICE)

    commoncalibdir = argoptions.commoncalibdir
    calibrateddir = argoptions.calibrateddir
    reduceddir = "./"

    common = []
    reduced = []
    calibrated = []

    if argoptions.loop=='TRUE':
        Nloop = int(24*3600./dtime)# 24 hours
    else:
        Nloop = 1
    loop_counter = 0
    db = None

    first = True
    while loop_counter<Nloop:

        # Compute the TF and visibilities
        if argoptions.tf=='TRUE' or argoptions.tf=='OVERWRITE':
            if loop_counter == 0:
                ge.add_gravity (common, glob.glob(commoncalibdir+'/GRAVI*fits'))

            ge.add_gravity (reduced, glob.glob(reduceddir+'/GRAVI*.fits'))
            ge.compute_tf (reduced, reduced+common, calibrateddir, options=argoptions, overwrite=True if argoptions.tf=='OVERWRITE' else False)
            
        if argoptions.viscal=='TRUE' or argoptions.viscal=='OVERWRITE':
            ge.add_gravity (calibrated, glob.glob(calibrateddir+'/GRAVI*.fits'))
            ge.add_gravity (reduced, glob.glob(reduceddir+'/GRAVI*.fits'))
            ge.calibrate_vis (reduced, calibrated, calibrateddir, options=argoptions, overwrite=True if argoptions.viscal=='OVERWRITE' else False)
 
        ##
        # opening a in memory data base
        if db is None:
            if os.path.exists("oivisdb.db"):
                log("Using the existing 'oivisdb.db' data base", 1, NOTICE)
            else:
                log("Creating a new data base 'oivisdb.db'", 1, NOTICE)
            db = gt.oivisdb.OIVisDB("oivisdb.db")
            
        ##
        # load the RAW and REDUCED OIFITS files
        if argoptions.load_data=='TRUE':
            log("Load RAW OIFITS files", 1, NOTICE)
            fls = glob.glob(reduceddir+"/GRAV*.fits")
            cProfile.run( 'nfeed = db.feedall(fls)','db_feedall.stat')

            if argoptions.tf=='OVERWRITE':
                log("Delete existing TF in db", 1, NOTICE)
                db.delete_protacg("TF_%_SCI")

            if argoptions.viscal=='OVERWRITE':
                log("Delete existing calibrated files in db", 1, NOTICE)
                db.delete_protacg("%CALIBRATED")
                 
            log("Load tf and calibrated OIFITS files", 1, NOTICE)
            fls = glob.glob(calibrateddir+"/GRAV*.fits")
            nfeed += db.feedall(fls)
        else:
            log("Loading file is skipped", 1, NOTICE)
            nfeed = 1

        if not nfeed and not first:
            log("Nothing new to plot wait %.1f min for new files"%(dtime/60.), 1, NOTICE)
            time.sleep(dtime)
            continue
        first = False

        ##
        # update the wavelength min and max
        # need to be after all file has been fed
        if argoptions.load_data=='TRUE':
            wrange = (2.15e-6, 2.25e-6)
            log("Restrict Wavelengths range between %.2e and %.2e"%wrange, 1, NOTICE)
            db.update_wave_index( wrange )

        # Cleanup the data base
        log("Cleanup from MJD<0 and STA_INDEX>99", 1, NOTICE)
        db.delete_constrains("MJD<30000 or STA1_INDEX>99")
        db.db.commit()
        
        try:
            os.mkdir("./trends")
            log("Directory ./trends created", 1, NOTICE)
        except OSError:
            pass

        #####
        # plots
        if argoptions.plot_data=='TRUE':
            log("Start plots", 1, NOTICE)

            # gt.plots.plot_all_trending(db)
        
            log("Remove calibrated", 1, NOTICE)
            db.delete_protacg("%CALIBRATED")

        
            log("Init dictionaries", 1, NOTICE)
            gt.plots.init_dictionaries(db)
                
            cProfile.run( 'gt.plots.plot_all_trending(db)', 'plot_all_trending.stat')
        
            log("Keep only RAW", 1, NOTICE)
            db.delete_protacg("%_CALIBRATED")
            db.delete_protacg("%_TF")
        
            gt.plots.plot_all_correlations(db)
        
            db.db.rollback()
        
            gt.plots.plot_all_uv(db)

            log("Keep only CALIBRATED", 1, NOTICE)
            db.delete_protacg("%_TF")
            db.delete_protacg("%_VIS")

            gt.plots.plot_all_target(db)
            db.db.rollback()
        
            gt.plots.make_html()

        loop_counter += 1
        if loop_counter<Nloop:
            log("wait %.1f min for new files"%(dtime/60.), 1, NOTICE)
            time.sleep(dtime)

