#! /usr/bin/env python3
"""
p2p_processing is part of pyGMTSAR.
Migrated from p2p_processing.csh (Dunyu Liu, 20230202).

Entry script: parses CLI args, loads/generates the per-case config, then
dispatches to the P2P stage functions in p2p_stages.py.

Syntax:  p2p_processing SAT Image1 Image2 [config.py]
"""
import sys, os, re
import subprocess, glob
from gmtsar_lib import *
from p2p_stages import *


def p2p_processing(debug):
    # 
    # check the number of arguments
    n = len(sys.argv)
    # If using p2p_processing A B C D, then a total of 5 input parameters are expected.
    
    if n!=4 and n!=5:   
        print( ' ')
        print( 'Usage: p2p_processing SAT master_image aligned_image [Python configuration_file] ')
        print( ' ')
        print( 'Example: p2p_processing ALOS IMG-HH-ALPSRP055750660-H1.0__A IMG-HH-ALPSRP049040660-H1.0__A [config.alos.py]')
        print( ' ')
        print( '    Put the data and orbit files in the raw folder, put DEM in the topo folder')
        print( '    The SAT needs to be specified, choices with in ERS, ENVI, ALOS, ALOS_SLC, ALOS2, ALOS2_SCAN')
        print( '    S1_STRIP, S1_TOPS, ENVI_SLC, CSK_RAW, CSK_SLC, TSX, RS2, GF3')
        print( ' ')
        print( '    Make sure the files from the same date have the same stem, e.g. aaaa.tif aaaa.xml aaaa.cos aaaa.EOF, etc')
        print( ' ')
        print( '    If [Python the configuration file] flag is left blank, the program will generate a default one using p2p_config')
        print( '    with default parameters ')
        print( ' ')
        sys.exit('ERROR: the number of arguments is not correct.') 
        sys.exit('ERROR: please provide the necessary input file(s) as required.')
    
    SAT = sys.argv[1]
    print('P2P 0: the satellite is ', SAT)
    print('P2P 0: check if a customized configuration file config.py exists ... ...')
    if n==5:
        if check_file_report(sys.argv[4]) == False:
            print('P2P 0: WARNING: the 4th arg config.py is required but missing ... ...')
            print('P2P 0: WARNING: a default config.py is being generated ... ...')
            run('pop_config ' + SAT)
        elif check_file_report(sys.argv[4]) == True:
            print('P2P 0: a customized config.py is provided and will be used to tune GMTSAR workflow ... ...')
    elif n==4: 
        print('P2P 0: no config.py is provided ... ...')
        print('P2P 0: and a default one will be generated by p2p_config ... ...')
        run('pop_config ' + SAT)
    
    print('P2P 0: read in parameters from the config.py ... ...')
    sys.path.insert(0, os.getcwd())
    import config
    from config import proc_stage, skip_stage, skip_master, \
        skip_1, skip_2, skip_3, skip_4, skip_5, skip_6, \
        num_patches, earth_radius, near_range, fd1, region_cut, \
        topo_phase, topo_interp_mode, shift_topo, switch_master, \
        filter_wavelength, dec_factor, compute_phase_gradient, \
        correct_iono, iono_filt_rng, iono_filt_azi, \
        iono_dsamp, iono_skip_est, threshold_snaphu, \
        near_interp, mask_water, defomax, threshold_geocode
    
    print('P2P 0: proc_stage   =',proc_stage)
    print('P2P 0: skip_stage   =',skip_stage)
    print('P2P 0: skip_master  =',skip_master)
    print('P2P 0: num_patches  =',num_patches)
    print('P2P 0: earth_radius =',earth_radius)
    print('P2P 0: near_range   =',near_range)
    print('P2P 0: fd1          =',fd1)
    print('P2P 0: region_cut   =',region_cut)
    print('P2P 0: topo_phase   =',topo_phase)
    print('P2P 0: topo_interp_mode =',topo_interp_mode)
    print('P2P 0: shift_topo   =',shift_topo)
    print('P2P 0: switch_master=',switch_master)
    print('P2P 0: filter_wavelength =', filter_wavelength)
    print('P2P 0: dec_factor   =',dec_factor)
    print('P2P 0: compute_phase_gradient =',compute_phase_gradient)
    print('P2P 0: correct_iono =',correct_iono)
    print('P2P 0: iono_filt_rng=',iono_filt_rng)
    print('P2P 0: iono_filt_azi=',iono_filt_azi)
    print('P2P 0: iono_dsamp   =',iono_dsamp)
    print('P2P 0: iono_skip_est=',iono_skip_est)
    print('P2P 0: threshold_snaphu=',threshold_snaphu)
    print('P2P 0: near_interp  =',near_interp)
    print('P2P 0: mask_water   =',mask_water)
    print('P2P 0: defomax      =',defomax)
    print('P2P 0: threshold_geocode', threshold_geocode)
    
    stage = proc_stage
    s_stage = skip_stage
    
    print('P2P 0: loading skip_stage flags skip_i (i=1-6) from config.py ... ...')
    print('P2P 0: for example, skip_1 = 1(0) for skipping(processing) this stage ... ...')
    print('P2P 0: skip_1 = ', skip_1)
    print('P2P 0: skip_2 = ', skip_2)
    print('P2P 0: skip_3 = ', skip_3)
    print('P2P 0: skip_4 = ', skip_4)
    print('P2P 0: skip_5 = ', skip_5)
    print('P2P 0: skip_6 = ', skip_6)
    
    if s_stage != -999:
         
        print('P2P 0: skipping stages are ', s_stage, ' ... ...')
    
    if skip_master == 2:
        skip_4 = 1
        skip_5 = 1
        skip_6 = 1
        print('P2P 0: skipping stages 4, 5, and 6 as skip_master is set to 2 ...')
    
    filter  = filter_wavelength
    iono    = correct_iono
    dec     = dec_factor
    master  = sys.argv[2]
    aligned = sys.argv[3]  
    
    # spec_div could be missing.
    if 'spec_div' in dir(config):
        from config import spec_div
    else:
        spec_div = 0
    
    # spec_mode could be missing.
    if 'spec_mode' in dir(config):
        from config import spec_mode
    else:
        spec_mode = -999

    # switch_land could be missing 
    if 'switch_land' in dir(config):
        from config import switch_land
    else: 
        switch_land = -999
    print('P2P 0: switch_land =', switch_land)    
    
    # range_dec could be missing
    if 'range_dec' in dir(config):
        from config import range_dec
    else:
        range_dec   = -999
    
    # azimuth_dec could be missing
    if 'azimuth_dec' in dir(config):
        from config import azimuth_dec 
    else:
        azimuth_dec = -999
        
    if 'SLC_factor' in dir(config):
        from config import SLC_factor 
    else: 
        SLC_factor  = -999        
    print('P2P 0: non-conventional configuration parameters are loaded ... ...')
    print('P2P 0: spec_div    =',spec_div)
    print('P2P 0: spec_mode   =',spec_mode)
    print('P2P 0: switch_land =',switch_land)
    print('P2P 0: range_dec   =',range_dec)
    print('P2P 0: azimuth_dec =',azimuth_dec)
    print('P2P 0: SLC_factor  =',SLC_factor)
    print('P2P 0: Finished loading configuration parameters.')
     
    print('P2P 0: combining preprocess paramters to cmdAppendix.')
    cmdAppendix = ' '
    if earth_radius != -999:
        cmdAppendix += ' -radius ' + str(earth_radius)
    if num_patches != -999:
        cmdAppendix += ' -npatch ' + str(num_patches)
    if SLC_factor != -999:
        cmdAppendix += ' -SLC_factor ' + str(SLC_factor)
    if spec_div !=0:
        cmdAppendix += ' -ESD ' + str(spec_mode)
    if skip_master !=-999:
        cmdAppendix += ' -skip_master ' + str(skip_master)
    print('P2P 0: commadline appendix is ', cmdAppendix)
    
    # NB: threshold_geocode / threshold_snaphu / iono_skip_est were previously
    # force-zeroed here for SAT=='S1_TOPS'. That made the multi-subswath Frame
    # workflow work (per-subswath skips snaphu+geocode, merge handles them)
    # but silently broke standalone single-subswath S1_TOPS runs like
    # Ridgecrest H_res. The override now lives in p2p_S1_TOPS_Frame's
    # processOneSubswath via _override_thresholds — narrowly scoped to the
    # Frame context. Standalone callers see the config they supplied.


    if stage == 1 and skip_1 == 0:
        P2P1Preprocess(SAT, master, aligned, skip_master, cmdAppendix)
    if debug==1:
        input('Press Enter to continue to Phase 2...')

    if (stage <=2 and skip_2 ==0):
        print('P2P 2: start from focus and align SLC images') 
        run('mkdir -p SLC')
    
        if (iono == 1):
            print('P2P 2: creating SLC_L and SLC_H for iono==1')
            run('mkdir -p SLC_L SLC_H')
        if (SAT == 'S1_TOPS'):
            master, aligned = renameMasterAlignedForS1tops(master, aligned)
        if SAT in ('NSR_A', 'NSR_B'):
            master, aligned = renameMasterAlignedForNSR(master, aligned, SAT)
        print(f'master, aligned after rename for {SAT}:', master, aligned)
        P2P2Clean(SAT, master, aligned, skip_master, iono)
        os.chdir('SLC')
        P2P2FocusAlign(SAT, master, aligned, skip_master, iono)
        # NSR_A/B skips region_cut per legacy csh; everything else honors it.
        if region_cut != -999 and SAT not in ('NSR_A', 'NSR_B'):
            P2P2RegionCut(master, aligned, skip_master, iono, region_cut)
        os.chdir('..')
        print('P2P 2: ALIGN.CSH - END')
    if debug==1:
        input('Press Enter to continue to Phase 3...')

    if stage <=3 and skip_3 == 0:
        P2P3MakeTopo(master, aligned, topo_phase, topo_interp_mode, shift_topo)
    if debug==1:
        input('Press Enter to continue to Phase 4...')
    
    ref, rep = switchMasterAligned(switch_master, master, aligned)
    
    if stage <= 4 and skip_4 == 0:    
        P2P4MakeFilterInterferograms(ref, rep, topo_phase, shift_topo, range_dec, azimuth_dec, 
                                    dec, filter, compute_phase_gradient, iono, iono_dsamp)
    if debug==1:
        input('Press Enter to continue to Phase 5...')
        
    if stage <=5 and skip_5 == 0:
        P2P5Unwrap(ref, rep, threshold_snaphu, mask_water, switch_land, near_interp, defomax)
    if debug==1:
        input('Press Enter to continue to Phase 6...')
    
    if stage <=6 and skip_6 == 0:
        P2P6Geocode(ref, rep, threshold_geocode, topo_phase)
    print('P2P 7: p2p_processing FINISHED')

if __name__ == "__main__":
    p2p_processing(debug=0)
