#!python
# coding: utf-8

import argparse

import os, sys
from desispec.scripts.proc_night import proc_night

def parse_args():
    """
    Creates an arguments parser for desi_proc_night to be given to scripts.proc_night
    """
    parser = argparse.ArgumentParser(description="Submit data for processing "
                                                  "with the DESI data pipeline.")

    parser.add_argument("-n","--night", type=int, default=None, help="The night you want processed.")
    parser.add_argument("--daily", action="store_true", help="If set the "
                        + "the pipeline operates in daily mode, updating"
                        + " the exposure_table, not submitting the last"
                        + " tile, waiting for a complete set of cals, etc.")
    parser.add_argument("--proc-obstypes", type=str, default=None, required=False,
                        help="The basic data obstypes to submit for processing. " +
                        "E.g. science, dark, flat, arc, zero.")
    parser.add_argument("--z-submit-types", type=str, default='cumulative', required=False,
                        help="The group types of redshifts that should be submitted with each exposure. If not "+
                        "specified, default  is 'cumulative'. If "+
                        "'false' or 'None' then no redshifts are submitted")
    parser.add_argument("--tiles", type=str, required=False, default=None,
                        help="Comma separated list of TILEIDs to include; use -99 to include arcs/flats")
    parser.add_argument("--surveys", type=str, required=False, default=None,
                        help="Comma separated list of surveys to include (e.g. sv1,sv3 or main); "+
                        "use --proc-obstypes to filter out arcs/flats if desired")
    parser.add_argument("--science-laststeps", type=str, required=False, default=None,
                        help="Comma separated list of LASTSTEP's to process "
                        + "(e.g. all, skysub, fluxcalib, ignore); "
                        + "by default we only process 'all'.")
    # File and dir defs
    #parser.add_argument("-s", "--specprod", type=str, required=False, default=None,
    #                    help="Subdirectory under DESI_SPECTRO_REDUX to write the output files. "+\
    #                         "Overwrites the environment variable SPECPROD")
    parser.add_argument("-q", "--queue", type=str, required=False, default=None,
                        help="The queue to submit jobs to. Default is realtime.")
    parser.add_argument("-r", "--reservation", type=str, required=False, default=None,
                        help="The reservation to submit jobs to. If None, it is not submitted to a reservation.")
    parser.add_argument("--system-name", type=str, required=False, default=None,
                        help="Batch system name, e.g. cori-haswell, cori-knl, perlmutter-gpu, ...")
    parser.add_argument("--exp-table-pathname", type=str, required=False, default=None,
                        help="Directory and file name where the output exposure table should be saved.")
    parser.add_argument("--proc-table-pathname", type=str, required=False, default=None,
                        help="Directory and file name where the output processing table should be saved.")
    parser.add_argument("--update-exptable", action="store_true", help="If true then the "
                        + "exposure table is updated. The default is False.")
    parser.add_argument("--complete-tiles-thrunight", type=int, required=False, default=None,
                        help="Only tiles completed on or before the supplied YYYYMMDD are "
                        +"considered complete and will be processed. None will process "
                        +"all completed tiles.")
    parser.add_argument("--sub-wait-time", type=float, required=False, default=0.1,
                        help="Time to wait between submissions.")
    parser.add_argument("--n-nights-darks", type=int, default=None, required=False,
                        help="Number of nights of darks to process. Default is to use the function's default.")
    parser.add_argument("--badcamword", type=str, default=None, required=False,
                        help="Badcamword to apply to all new data in the exposure tables and to apply to linkcal and biaspdark jobs.")
    parser.add_argument("--badamps", type=str, default=None, required=False,
                        help="Badamps to apply to all new data in the exposure tables and to apply to linkcal and biaspdark jobs.")
    # Code Flags
    parser.add_argument("--dry-run", action="store_true",
                        help="Perform a dry run where no jobs are actually created or submitted. Overwritten if "+
                        "dry-run-level is defined as nonzero.")
    parser.add_argument("--dry-run-level", type=int, default=0,
                        help="What level of dry_run to perform, if any. Default is 0. "
                        + "0 which runs the code normally. "
                        + "1 writes all files but doesn't submit any jobs to Slurm. "
                        + "2 writes tables but doesn't write scripts or submit anything. "
                        + "3 Doesn't write or submit anything but queries Slurm normally for job status. "
                        + "4 Doesn't write, submit jobs, or query Slurm."
                        + "5 Doesn't write, submit jobs, or query Slurm; instead it makes up the status of the jobs.")
    
    parser.add_argument("--no-redshifts", action="store_true",
                        help="Whether to submit redshifts or not. If set, redshifts are not submitted.")
    parser.add_argument("--ignore-proc-table-failures", action="store_true",
                        help="Give this flag if you want to submit jobs even if "+
                        " there are incomplete jobs in the existing proc table."+
                        " Only to be used after vetting proc table failures.")
    parser.add_argument("--dont-check-job-outputs", action="store_true",
                        help="If all files for a pending job exist and this is False, then the script will not be "+
                        "submitted. If some files exist and this is True, only the "+
                        "subset of the cameras without the final data products will be generated and submitted.")
    parser.add_argument("--dont-resubmit-partial-jobs", action="store_true",
                        help="Must be False if --dont-check-job-outputs is False. If False, jobs with some prior data "+
                        "are pruned using PROCCAMWORD to only process the remaining cameras not found to exist.")
    parser.add_argument("--all-tiles", action="store_true",
                        help="Set to NOT restrict to completed tiles as defined by the table pointed to by specstatus_path.")
    parser.add_argument("--all-cumulatives", action="store_true",
                        help="Set to run cumulative redshifts for all tiles"
                        + "even if the tile has observations on a later night.")
    parser.add_argument("--specstatus-path", type=str, required=False, default=None,
                        help="Location of the surveyops specstatus table. Default is "+
                        "$DESI_SURVEYOPS/ops/tiles-specstatus.ecsv")
    parser.add_argument("--use-specter", action="store_true",
                        help="Use specter. Default is to use gpu_specter")
    parser.add_argument("--no-cte-flats", action="store_true",
                        help="If flag set then cte flat exposures are "
                        + "not processed for cte identification.")
    parser.add_argument("--dont-require-cals", action="store_true",
                        help="If set then the code requires either a valid set "
                        + "of calibrations or a valid override file to link"
                        + " to calibrations in order to proceed with "
                        + "science processing.")
    parser.add_argument("--psf-linking-without-fflat", action="store_true",
                        help="If set then the code will NOT raise an error "
                        + "if asked to link psfnight calibrations "
                        + "without fiberflatnight calibrations.")
    parser.add_argument("--no-resub-failed", action="store_true", required=False,
                        help="Give this flag if you do NOT want to resubmit " +
                        "jobs with Slurm status 'FAILED' by default.")
    parser.add_argument("--no-resub-any", action="store_true", required=False,
                        help="Give this flag if you do NOT want to resubmit jobs.")
    parser.add_argument("--still-acquiring", action='store_true',
                        help="for testing --daily mode, assume more data is still coming even if "
                        + "outside of normal observing hours.")
    
    
    args = parser.parse_args()
    
    # convert str lists to actual lists
    if args.proc_obstypes is not None:
         args.proc_obstypes = [pobstype.strip().lower() for pobstype in
                               args.proc_obstypes.split(',')]

    if args.tiles is not None:
         args.tiles = [int(tileid) for tileid in args.tiles.split(',')]

    if args.surveys is not None:
         args.surveys = [survey.strip().lower() for survey in args.surveys.split(',')]

    if args.science_laststeps is not None:
         args.science_laststeps = [laststep.strip().lower() for laststep in
                                  args.science_laststeps.split(',')]

    if args.z_submit_types.lower() in ['false', 'none']:
         args.z_submit_types = None
         args.no_redshifts = True
    else:
         args.z_submit_types = [ztype.strip().lower() for ztype in
                                  args.z_submit_types.split(',')]

    return args

if __name__ == '__main__':
    args = parse_args()
    proc_night(**args.__dict__)
