#!/usr/bin/env python3

import click
import cloup
from cloup.constraints import mutually_exclusive, RequireExactly, IsSet, If
import numpy as np
import warnings
warnings.filterwarnings("ignore")
from MapLines.tools.line_fit import line_fit,line_fit_single
import MapLines.tools.tools as tol
import os.path as ptt

@click.group('run_mapline', short_help='CLI for the emission line mapper')
def cli():
    pass


@cloup.command(short_help='Run the emission line mapper')
@click.option('-g', '--config_file', type=str, default='', help='name of the config file')
@click.option('-n', '--name', type=str, help='name of the IFS cube')
@click.option('-o', '--name_out', type=str, default='None', help='name of the output files')
@click.option('-m', '--mask', type=str, default='test', help='name of the mask map')
@click.option('-p', '--path',     type=str, default='', help='path to the data cubes')
@click.option('-y', '--path_out', type=str, default='outputs/', help='path of the output files')
@click.option('-c', '--ncpus', type=int, default=10, help='number of CPUs')
@click.option('-k', '--kskew', is_flag=True, default=False,help='flag to run skew line profile mode')
@click.option('-x', '--outflow', is_flag=True, default=False,help='flag to run outflow line profile mode')
@click.option('-t', '--test', is_flag=True, default=False,help='flag to run the full analysis')
@click.option('-e', '--error', is_flag=True, default=False,help='flag to run autocalculate the error vector')
@click.option('-z', '--zt', type=float, default=0, help='redshift of the object')
@click.option('-b', '--bcont', is_flag=True, default=False,help='flag to run deactivate autosubstract continum')
@click.option('-s', '--sprogressd', is_flag=True, default=False,help='deactivate the progress bar')
@click.option('-i', '--it', type=int, default=0, help='i index for test, default nx/2')
@click.option('-j', '--jt', type=int, default=0, help='j index for test, default ny/2')
@click.option('-l', '--lorentz', is_flag=True, default=False,help='activate the lorenztiant profile')
@click.option('-f', '--fluxf', type=float, default=1.0, help='flux factor')
@click.option('-q', '--line_config', type=str, default='line_prop.yml', help='line model configuration file')
@click.option('-w', '--line_config_path', type=str, default='', help='path to the line model configuration file')

def run(config_file,name,mask,path,path_out,zt,ncpus,test,error,bcont,it,jt,sprogressd,name_out,kskew,outflow,lorentz,fluxf,line_config,line_config_path):
    wave_ini=6350.0
    wave_fin=6850.0
    wave_AB=False
    waveR=''
    data=tol.read_config_file(config_file)
    if data:
        typeF=data['files'][0]['object_type']
        if 'IFS' in typeF:
            name=data['files'][0]['object_name']
            mask=data['files'][0]['mask']
            path=data['files'][0]['path']
            path_out=data['files'][0]['path_out']
            zt=data['files'][0]['zt']
            ncpus=data['files'][0]['ncpus']
            test=data['files'][0]['test']
            error=data['files'][0]['error']
            bcont=data['files'][0]['bcont']
            it=data['files'][0]['it']
            jt=data['files'][0]['jt']
            sprogressd=data['files'][0]['sprogressd']
            name_out=data['files'][0]['name_out']
            kskew=data['files'][0]['kskew']
            outflow=data['files'][0]['outflow']
            lorentz=data['files'][0]['lorentz']
            waveR='_'+data['files'][0]['wave_range']
            wave_ini=data['files'][0]['wave_ini']
            wave_fin=data['files'][0]['wave_fin']
            if not 'None' in str(wave_ini) and wave_ini > 0:
                if not 'None' in str(wave_fin) and wave_fin > 0:
                    wave_AB=True
            fluxf=data['files'][0]['fluxf']
            fluxf=float(fluxf)
            line_config=data['files'][0]['line_config']
            line_config_path=data['files'][0]['line_config_path']
        else:
            print('Error: The config file is not for IFS spectra')
            return

    if name_out == 'None':
        name_out=name

    if test:
        pgr_bar=False
        plot_f=True
    else:
        plot_f=False
        if sprogressd:
            pgr_bar=False
        else:
            pgr_bar=True
    if bcont:
        cont=False
    else:
        cont=True
    if error:
        error_c=False
    else:
        error_c=True
    if kskew:
        skew=True
        skl='_skew'
    else:
        skew=False
        skl=''
    if outflow:
        outf=True
        soutf='_outflow'
    else:
        outf=False
        soutf=''
    if wave_AB:
        lA1=wave_ini
        lA2=wave_fin    
    dirt=path
    dir_out=path_out
    file1=dirt+'NAME.fits.gz'.replace('NAME',name)
    file2=dirt+'NAME.fits.gz'.replace('NAME',name)
    file3=dirt+'NAMEM.fits.gz'.replace('NAMEM',mask)  
    if ptt.exists(dir_out) == False:
        tol.sycall('mkdir -p '+dir_out)
    file_out=dir_out+'NAME_modelsV2'.replace('NAME',name_out)+waveR+skl+soutf
    file_out2=dir_out+'NAME_paramV2'.replace('NAME',name_out)+waveR+skl+soutf
    name_out2=name_out+waveR+skl+soutf
    config_lines=line_config_path+line_config
    line_fit(file1,file2,file3,file_out,file_out2,name_out2,z=zt,lA1=lA1,lA2=lA2,plot_f=plot_f,
         pgr_bar=pgr_bar,ncpu=ncpus,skew=skew,flux_f=fluxf,erft=0.75,cont=cont,test=test,
         error_c=error_c,i_t=it,j_t=jt,lorentz=lorentz,config_lines=config_lines,outflow=outf,dir_out=dir_out)
    
cli.add_command(run)

@cli.command('runoned', short_help='obtain the spectra model')
@click.option('-g', '--config_file', type=str, default='', help='name of the config file')
@click.option('-n', '--name', type=str, help='name of the spectra file')
@click.option('-o', '--name_out', type=str, default='None', help='name of the output files')
@click.option('-p', '--path',     type=str, default='', help='path to the data cubes')
@click.option('-y', '--path_out', type=str, default='outputs/', help='path of the output files')
@click.option('-c', '--ncpus', type=int, default=10, help='number of CPUs')
@click.option('-k', '--kskew', is_flag=True, default=False,help='flag to run skew line profile mode')
@click.option('-u', '--outflow', is_flag=True, default=False,help='flag to run outflow line profile mode')
@click.option('-e', '--error', is_flag=True, default=False,help='flag to run autocalculate the error vector')
@click.option('-z', '--zt', type=float, default=0, help='redshift of the object')
@click.option('-b', '--bcont', is_flag=True, default=False,help='flag to run deactivate autosubstract continum')
@click.option('-f', '--fluxf', type=float, default=1.0, help='flux factor')
@click.option('-l', '--lorentz', is_flag=True, default=False,help='activate the lorenztiant profile')
@click.option('-i', '--input_format', type=str, default='CSV', help='input of the spectra file')
@click.option('-q', '--line_config', type=str, default='line_prop.yml', help='line model configuration file')
@click.option('-w', '--line_config_path', type=str, default='', help='path to the line model configuration file')
@click.option('-m', '--smoth', is_flag=True, default=False, help='flag to activate a smothing of the spectra')
@click.option('-h', '--ker', type=float, default=2, help='value in pixels of the smothin kernel')

def runoned(config_file,name,path,path_out,zt,ncpus,error,bcont,name_out,kskew,outflow,fluxf,lorentz,input_format,line_config,line_config_path,smoth,ker):
 
    wave_ini=6350.0
    wave_fin=6850.0
    wave_AB=False
    waveR=''

    data=tol.read_config_file(config_file)
    if data:
        typeF=data['files'][0]['object_type']
        if 'OneD' in typeF:
            name=data['files'][0]['object_name']
            name_out=data['files'][0]['name_out']
            path=data['files'][0]['path']
            path_out=data['files'][0]['path_out']
            ncpus=data['files'][0]['ncpus']
            kskew=data['files'][0]['kskew']
            outflow=data['files'][0]['outflow']
            error=data['files'][0]['error']
            zt=data['files'][0]['zt']
            bcont=data['files'][0]['bcont']
            waveR=data['files'][0]['wave_range']
            wave_ini=data['files'][0]['wave_ini']
            wave_fin=data['files'][0]['wave_fin']
            if not 'None' in str(wave_ini) and wave_ini > 0:
                if not 'None' in str(wave_fin) and wave_fin > 0:
                    wave_AB=True
            fluxf=data['files'][0]['fluxf']
            lorentz=data['files'][0]['lorentz']
            input_format=data['files'][0]['input_format']
            line_config=data['files'][0]['line_config']
            line_config_path=data['files'][0]['line_config_path']
            smoth=data['files'][0]['smoth']
            ker=data['files'][0]['ker']
        else:
            print('Error: The config file is not for 1D spectra')
            return

    if name_out == 'None':
        name_out=name
    if bcont:
        cont=False
    else:
        cont=True
    if error:
        error_c=False
    else:
        error_c=True
    if kskew:
        skew=True
        skl='_skew'
    else:
        skew=False
        skl=''
    if outflow:
        outf=True
        soutf='_outflow'
    else:
        outf=False
        soutf=''    
    if wave_AB:
        lA1=wave_ini
        lA2=wave_fin  
    flux_f=fluxf        
    dirt=path
    dir_out=path_out
    if input_format == 'CSV':
        file1=dirt+'NAME.csv'.replace('NAME',name)
    elif input_format == 'ASCII':
        file1=dirt+'NAME.txt'.replace('NAME',name)
    elif input_format == 'IrafFits' or input_format == 'TableFits' or input_format == 'SDSS':
        file1=dirt+'NAME.fits'.replace('NAME',name)           
    else:
        file1=dirt+'NAME'
    if ptt.exists(dir_out) == False:
        tol.sycall('mkdir -p '+dir_out)

    file_out=dir_out+'NAME_modelsV2'.replace('NAME',name_out)+waveR+skl+soutf
    file_out2=dir_out+'NAME_paramV2'.replace('NAME',name_out)+waveR+skl+soutf
    name_out2=name_out+waveR+skl+soutf
    config_lines=line_config_path+line_config
    line_fit_single(file1,file_out,file_out2,name_out2,input_format=input_format,z=zt,lA1=lA1,lA2=lA2,ncpu=ncpus,smoth=smoth,ker=ker,
         lorentz=lorentz,skew=skew,flux_f=flux_f,erft=0.75,cont=cont,error_c=error_c,config_lines=config_lines,outflow=outf,dir_out=dir_out)



if __name__ == "__main__":
    cli()
