#!/Users/mathewj2/repos/SPT/venv/bin/python
import argparse
import subprocess
from subprocess import PIPE
from shutil import which
import os
from os.path import join

import spatialprofilingtoolbox as spt


if __name__=='__main__':
    parser = argparse.ArgumentParser(
        description = ''.join([
            'The entry point into SPT (Spatial Profiling Toolbox) ',
            'commands.',
        ])
    )
    generate_jobs = 'generate-jobs'
    semantic_parse = 'semantic-parse'
    list_auxiliary_job_inputs = 'list-auxiliary-job-inputs'
    list_all_jobs_inputs = 'list-all-jobs-inputs'
    list_all_compartments = 'list-all-compartments'
    single_job = 'single-job'
    aggregate_results = 'aggregate-results'
    run = 'run'
    configure = 'configure'
    write_nextflow_script = 'write-nextflow-script'
    commands = [generate_jobs, semantic_parse, list_auxiliary_job_inputs, list_all_jobs_inputs, list_all_compartments, single_job, aggregate_results, run, configure, write_nextflow_script]
    parser.add_argument(
        'command_token',
        nargs='?',
        choices = commands,
    )
    parser.add_argument('--input-file-identifier',
        dest='input_file_identifier',
        type=str,
        required=False,
        help='An input file identifier, as it appears in the file manifest.',
    )
    parser.add_argument('--fov',
        dest='fov_index',
        type=int,
        required=False,
        help=''.join([
            'Indication of field of view to consider (one-based integer ',
            'index). Only pertains to some workflows.',
        ])
    )
    parser.add_argument('--job-inputs',
        dest='job_inputs',
        type=str,
        required=False,
        help=''.join([
            'Filename for output list of additional inputs to every job.',
        ])
    )
    parser.add_argument('--all-jobs-inputs',
        dest='all_jobs_inputs',
        type=str,
        required=False,
        help=''.join([
            'Filename for output list of additional inputs to all jobs.',
        ])
    )
    parser.add_argument('--compartments-file',
        dest='compartments_file',
        type=str,
        required=False,
        help=''.join([
            'Filename for output list of compartment names.',
        ])
    )
    parser.add_argument('--intermediate-database-filename',
        dest='intermediate_database_filename',
        type=str,
        required=False,
        help=''.join([
            'Filename for sqlite database file storing intermediate results.',
        ])
    )
    args = parser.parse_args()
    parameters = {}
    value = args.input_file_identifier
    if value is not None:
        parameters['input_file_identifier'] = value
    value = args.fov_index
    if value is not None:
        parameters['fov_index'] = value
    value = args.job_inputs
    if value is not None:
        parameters['job_inputs'] = value
    value = args.all_jobs_inputs
    if value is not None:
        parameters['all_jobs_inputs'] = value
    value = args.compartments_file
    if value is not None:
        parameters['compartments_file'] = value
    value = args.intermediate_database_filename
    if value is not None:
        parameters['intermediate_database_filename'] = value

    command = args.command_token

    if not command in commands:
        exit()

    parameters = {**parameters, **spt.get_config_parameters()}
    if command == configure:
        spt.write_out_nextflow_script(
            parameters['sif_file'] if 'sif_file' in parameters else None,
            excluded_host_name = parameters['excluded_host_name'] if 'excluded_host_name' in parameters else None,
        )
        exit()

    if command == list_auxiliary_job_inputs:
        job_generator = spt.get_job_generator(**parameters)
        job_generator.list_auxiliary_job_inputs()

    if command == list_all_jobs_inputs:
        job_generator = spt.get_job_generator(**parameters)
        job_generator.list_all_jobs_inputs()

    if command == list_all_compartments:
        job_generator = spt.get_job_generator(**parameters)
        job_generator.list_all_compartments()

    if command == generate_jobs:
        job_generator = spt.get_job_generator(**parameters)
        job_generator.generate()

    if command == semantic_parse:
        with spt.get_semantic_source_parser(**parameters) as parser:
            parser.parse()

    if command == single_job:
        analyzer = spt.get_analyzer(**parameters)
        analyzer.calculate()

    if command == aggregate_results:
        integrator = spt.get_integrator(**parameters)
        integrator.calculate()

    if command == write_nextflow_script:
        spt.write_out_nextflow_script(
            parameters['sif_file'] if 'sif_file' in parameters else None,
            excluded_host_name = parameters['excluded_host_name'] if 'excluded_host_name' in parameters else None,
        )

    if command == run:
        if which('bsub') is None:
            config_file = spt.nf_config_file['local']
        else:
            config_file = spt.nf_config_file['lsf']
        nextflow_invoker = ['nextflow', '-c', config_file, 'run', spt.nf_script_file]
        if which(nextflow_invoker[0]) is None:
            print('You must install nextflow. The following command may do this:')
            print('  ' + ' '.join(['curl', '-s', 'https://get.nextflow.io', '|', 'bash']))
            exit()
        spt.write_out_nextflow_script(
            parameters['sif_file'] if 'sif_file' in parameters else None,
            excluded_host_name = parameters['excluded_host_name'] if 'excluded_host_name' in parameters else None,
        )
        subprocess.run(nextflow_invoker)
