import copy
import importlib
import inspect
import os
import sys
import time
import traceback

#Add unit-converter submodule to python load path
sys.path.append('{}/unit-converter'.format(os.path.abspath(inspect.getsourcefile(lambda:0)).split('/execute_stage')[0]))

from crossnetwork_processing_functions import get_configuration_variables, create_GHOST_stage_logfile 
from station_concatenate import StationConcatenate
from globally_gridded_metadata import GloballyGriddedMetadata
from quality_control import QualityControl
from temporal_codes import TemporalCodes
from station_temporal_average import StationTemporalAverage
from station_aggregate import StationAggregate
from data_product import DataProduct
from merge import Merge
from split_EBAS import SplitEBAS
from compress import Compress
from zip import Zip

###--------------------------------------------------------------------------------------------------###
#Get variables passed from job submittal script (variable by stage)
###--------------------------------------------------------------------------------------------------###

GHOST_stage = sys.argv[1]
if 'S' in GHOST_stage:
    slurm_job_ID, network, parameter, param_to_parallelise_by = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]
    log_file_ref = copy.deepcopy(param_to_parallelise_by)
elif GHOST_stage == 'T1':
    slurm_job_ID, network, parameter, station_reference, temporal_resolution_code, region = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7]
    log_file_ref = '{}_{}_{}'.format(station_reference,temporal_resolution_code,region)
elif GHOST_stage in ['T2','P1']:
    slurm_job_ID, network, parameter, yearmonth_str, temporal_resolution_code, region = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7]
    log_file_ref = '{}_{}_{}'.format(yearmonth_str,temporal_resolution_code,region)
elif GHOST_stage == 'E1':
    slurm_job_ID, network, parameter, temporal_resolution_code, region = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6]
    log_file_ref = '{}_{}'.format(temporal_resolution_code,region)
elif GHOST_stage == 'M1':
    slurm_job_ID, network, parameter, yearmonth_str, temporal_resolution_code = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6]
    log_file_ref = '{}_{}'.format(yearmonth_str,temporal_resolution_code)
elif GHOST_stage == 'C1':
    slurm_job_ID, network, parameter, temporal_resolution_code, region = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6]
    log_file_ref = '{}_{}'.format(temporal_resolution_code,region)
elif GHOST_stage == 'Z1':
    slurm_job_ID, network, parameter, region = sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]
    log_file_ref = '{}'.format(region)

###--------------------------------------------------------------------------------------------------###
#Execute stage processing
###--------------------------------------------------------------------------------------------------###
try:
    #get configuration variables
    run_details, parameter_details, network_details = get_configuration_variables(slurm_job_ID, network=network, parameter=parameter)

    #add start of stage processing
    run_details['stage_process_start_time'] = time.time()

    #initialise stage log file string
    run_details['log_file_str'] = ''

    #add log file name to run_details
    run_details['log_file_ref'] = log_file_ref

    #add GHOST stage to run_details
    run_details['GHOST_stage'] = GHOST_stage

    #execute stage
    if GHOST_stage == 'S1':
        if 'AERONET' in network:
            network_module = importlib.import_module('AERONET_processor')
        else:
            network_module = importlib.import_module(network+'_processor')
        process_inst = network_module.StandardiseNetworkData(param_to_parallelise_by,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'S2':
        process_inst = StationConcatenate(param_to_parallelise_by,run_details,parameter_details,network_details) 
        process_inst.do_work()
    elif GHOST_stage == 'S3': 
        process_inst = GloballyGriddedMetadata(param_to_parallelise_by,run_details,parameter_details,network_details)  
        process_inst.do_work()
        process_inst = QualityControl(process_inst)
        process_inst.do_work()
        process_inst = TemporalCodes(process_inst)
        process_inst.do_work()
    elif GHOST_stage == 'T1':
        process_inst = StationTemporalAverage(station_reference,temporal_resolution_code,region,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'T2':
        process_inst = StationAggregate(yearmonth_str,temporal_resolution_code,region,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'P1':
        process_inst = DataProduct(yearmonth_str,temporal_resolution_code,region,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'E1':
        process_inst = SplitEBAS(temporal_resolution_code,region,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'M1':
        process_inst = Merge(yearmonth_str,temporal_resolution_code,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'C1':
        process_inst = Compress(temporal_resolution_code,region,run_details,parameter_details,network_details)
        process_inst.do_work()
    elif GHOST_stage == 'Z1':
        process_inst = Zip(region,run_details,parameter_details,network_details)
        process_inst.do_work()

#write error log file if have uncaught error in stage
except Exception as e:
    process_inst.run_details['log_file_str'] += str(traceback.format_exc())
    create_GHOST_stage_logfile(3,process_inst.run_details)