import time
import argparse
from pathlib import Path

from src.surfEmis_driver import gen_surf_emis
from src.elevEmis_driver import gen_elev_emis

def main():

    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    
    parser.add_argument("-o","--output-options", help="S to produce 'Surface emissions data' \nE to produce 'Elevated emissions data'. \nAdd P to show the parameter list.", required=True)
    parser.add_argument("-syr", "--start-year", type=int, help="Starting year", required=True)
    parser.add_argument("-eyr", "--end-year", type=int, help="Ending year", required=True)
    parser.add_argument("-f", "--filename", nargs='+', help="Original emission data filename", required=True)
    parser.add_argument("-v", nargs='+', help="Variable names. \nFormat: species_mode. ex: bc_a1, so4_a2 etc.", default=None)
    parser.add_argument("-indir", help="Input directory. \nContains raw emissions, SCRIP, vertical distribution etc. files,", default=None)
    parser.add_argument("-outdir", help="Output directory. \nAll new emissions and intermediate data will be stored here.", default=None)
    parser.add_argument("-sout", help="Output surface emission file name. \nEnding string including the '.nc' for output NetCDF.", default=None)
    parser.add_argument("-eout", help="Output elevated emission file name. \nEnding string including the '.nc' for output NetCDF.", default=None)
    parser.add_argument("-res", help="Output resolution. \nFor SE-grid use 30 for ne30pg2 and so on. \nFor lat/lon use 180x360 for 1-deg and so on.", default=None)
    parser.add_argument("-grid", help="Output grid mesh or SCRIP file. \nThese files can be produced using the ggen tool.", default=None)
    parser.add_argument("-mean", help="Produce climatological mean.\nThe mean from syr to eyr.", action='store_true', default=None)
    parser.add_argument("-myr", help="Climatological mean year. \nThese are the model dates.", default=None)
    parser.add_argument("-profile", help="Profile data. \nVertical profile data used to produce vertical emissions.", default=None)
    parser.add_argument("-sect", nargs='+', help="List of sectors", default=None)
    parser.add_argument("-syrs", nargs='+', help="Starting year list", default=None)
    parser.add_argument("-eyrs", nargs='+', help="Ending year list", default=None)
    parser.add_argument("-flist", nargs='+', help="Original emission filenames list", default=None)
    parser.add_argument("-plist", nargs='+', help="Vertical profiles list", default=None)
    parser.add_argument("-diam", nargs='+', help="List of volume mean diameters", default=None)
    parser.add_argument("-mw", nargs='+', help="List of moelcular weights", default=None)
    parser.add_argument("-rho", nargs='+', help="List of densities", default=None)
    parser.add_argument("-frac", nargs='+', help="List of fractions", default=None)
    parser.add_argument("-sulfactor", nargs='+', help="List of sulfactors. \nThis is the ratio of sulfate (NH4)HSO4 mw and SO2 mw. \nDefault value used for sulfate aerosols is 115/64.", default=None)
    parser.add_argument("-numstr", nargs='+', help="List of number strings", default=None)
    parser.add_argument("-numfile", nargs='+', help="List of number file", default=None)
    parser.add_argument("-ncvar", nargs='+', help="List of variable names in raw files", default=None)
    parser.add_argument("-altitude", help="Altitudes for the elevated emissions data.", default=None)
    parser.add_argument("-fractions", help="Vertical fractional distribution. \nUsed in elevated emissions.", default=[0.25,0.15,0.15,0.1,0.1,0.1,0.05,0.05,0.05,0, 0, 0, 0])
    parser.add_argument("-ind_frac", help="Vertical fractional distribution for IND and ENE sectors.", default=[0.13,0.76,0.11,0,0,0,0,0,0,0, 0, 0, 0])
    parser.add_argument("-params", help="Parameter filename.\n Contains the default parameters.", default=None)
    parser.add_argument("-checker", help="Verify estimates. \nCompares original data with newly generated data.", action='store_true', default=None)
    parser.add_argument("-cgrid", help="Grid area data used when checker is True.", default=None)
    parser.add_argument("-sedata", help="Output in model native or SE-grid mesh. \nThis is by default True.", default=True)
    parser.add_argument("-species", help="Aerosol species name (ex: bc, pom etc.). \nUsed for species beyond default in place of -v option \nand in conjunction with -mode option", default=None)
    parser.add_argument("-mode", help="Aerosol mode (ex: 1, 2, 4 etc.). \nUsed for mode beond the default in place of -v option \nand in conjunction with -species option", default=None)
    parser.add_argument("-prep", help="Pre-process data from different sources. \nEx: 'GFED' for GFED4 biomass burning emissions.", default=None)
    
    args = parser.parse_args()
    out = args.output_options
    s = args.start_year
    e = args.end_year
    file = args.filename
    var = args.v
    indir = args.indir
    outdir = args.outdir
    res = args.res
    grid = args.grid
    mean = args.mean
    myr = args.myr
    sectors = args.sect
    syrList = args.syrs
    eyrList = args.eyrs
    flist = args.flist
    diam = args.diam
    mw = args.mw
    rho = args.rho
    frac = args.frac
    sulfactor = args.sulfactor
    numstr = args.numstr
    numfile = args.numfile
    ncvar = args.ncvar
    params = args.params
    checker = args.checker
    cgrid = args.cgrid
    sedata = args.sedata
    species = args.species
    profile = args.profile
    fractions = args.fractions
    ind_frac = args.ind_frac
    plist = args.plist
    mode = args.mode
    sout = args.sout
    eout = args.eout
    prep = args.prep
    
    timerOn = time.perf_counter()
    
    assert len(var) == len(file), "List of variables and files should have the same length!"
    
    if (out == 'SP'):
        for v, f in zip(var,file):
            init = gen_surf_emis(s,e,f.strip(),variable=v.strip(),indir=indir,outdir=outdir,res=res,grid=grid,\
                                      mean=mean,mean_yr=myr,sectors=sectors,syr_list=syrList,eyr_list=eyrList,\
                                      filenames=flist,diam=diam,mw=mw,rho=rho,frac=frac,sulfactor=sulfactor,\
                                      numstr=numstr,numfile=numfile,ncvar=ncvar,param_file=params,checker=checker,\
                                      cgrid=cgrid,SEdata=sedata,species=species,mode=mode)
            init.get_params()
        
    if (out == 'S'):
            
        if sout == None:
            ## Default tail end of the file name if not user defined.
            sout = 'E3SM_surf_emis.nc'
                
        for v, f in zip(var,file):
            init = gen_surf_emis(s,e,f.strip(),variable=v.strip(),indir=indir,outdir=outdir,res=res,grid=grid,\
                                      mean=mean,mean_yr=myr,sectors=sectors,syr_list=syrList,eyr_list=eyrList,\
                                      filenames=flist,diam=diam,mw=mw,rho=rho,frac=frac,sulfactor=sulfactor,\
                                      numstr=numstr,numfile=numfile,ncvar=ncvar,param_file=params,checker=checker,\
                                      cgrid=cgrid,SEdata=sedata,species=species,mode=mode,output=sout)
            
            init.prod_emis()

            ## The pre-processor creates a number emission files for each mass emission flux file. 
            ## Since both POM and BC are considered as primary carbon mode aerosols, those 2 files
            ## are combined after all mass emission flux files are generated.
            
            if ('a4' in init.numfile) and (len(list(Path(outdir).glob('num_a4_*_a4_'+init.ytag+'_'+sout))) == 2):
                init.combine_numvars('num_a4')
            if ('a1' in init.numfile):
                init.combine_numvars('num_a1')
            if ('a2' in init.numfile):
                init.combine_numvars('num_a2')
        
    if (out == 'EP'):
            
        for v, f in zip(var,file):
            init = gen_elev_emis(s,e,f.strip(),variable=v.strip(),indir=indir,outdir=outdir,res=res,grid=grid,\
                                      mean=mean,mean_yr=myr,sectors=sectors,syr_list=syrList,eyr_list=eyrList,\
                                      filenames=flist,diam=diam,mw=mw,rho=rho,frac=frac,sulfactor=sulfactor,\
                                      numstr=numstr,numfile=numfile,param_file=params,checker=checker,\
                                      cgrid=cgrid,SEdata=sedata,species=species,mode=mode,profile=profile,\
                                      profiles=plist,fractions=fractions,ind_frac=ind_frac)
            init.get_params()
        
    if (out == 'E'):
        
        if eout == None:
            eout = 'E3SM_elev_emis.nc'
                        
        for v, f in zip(var,file):
            init = gen_elev_emis(s,e,f.strip(),variable=v.strip(),indir=indir,outdir=outdir,res=res,grid=grid,\
                                      mean=mean,mean_yr=myr,sectors=sectors,syr_list=syrList,eyr_list=eyrList,\
                                      filenames=flist,diam=diam,mw=mw,rho=rho,frac=frac,sulfactor=sulfactor,\
                                      numstr=numstr,numfile=numfile,param_file=params,checker=checker,\
                                      cgrid=cgrid,SEdata=sedata,species=species,mode=mode,profile=profile,\
                                      profiles=plist,fractions=fractions,ind_frac=ind_frac,output=eout,prep=prep)
            init.prod_emis()
            
            if ('a4' in init.numfile) and (len(list(Path(outdir).glob('num_a4_*_a4_'+init.ytag+'_'+eout))) == 2):
                init.combine_numvars('num_a4')
            if ('a1' in init.numfile):
                init.combine_numvars('num_a1')
            if ('a2' in init.numfile):
                init.combine_numvars('num_a2')
        
    timerOff = time.perf_counter()
    print(f'\nFinished in {round(timerOff-timerOn, 2)} second(s)')
    
