#!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'
    list_auxiliary_job_inputs = 'list-auxiliary-job-inputs'
    single_job = 'single-job'
    aggregate_results = 'aggregate-results'
    run = 'run'
    configure = 'configure'
    commands = [generate_jobs, list_auxiliary_job_inputs, single_job, aggregate_results, run, configure]
    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('--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.intermediate_database_filename
    if value is not None:
        parameters['intermediate_database_filename'] = value

    command = args.command_token

    parameters = {**parameters, **spt.get_config_parameters()}
    if command == configure:
        exit()

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

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

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

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

    if (not command in commands) or command == run:
        nextflow_invoker = ['nextflow']
        if which('nextflow') is None:
            print('Installing nextflow.')
            download_file = join(os.getcwd(), 'nfdownload.sh')
            subprocess.run(['curl', '-s', 'https://get.nextflow.io', '-o', download_file])
            subprocess.run(['bash', download_file])
            path_string = os.environ['PATH']
            paths = path_string.strip('\n').split(':')
            if not '~/bin' in paths:
                print('Warning: ~/bin/ is not on the executable path, so nextflow will only be installed in this exact directory.')
                nextflow_invoker = ['bash', download_file]
            else:
                nf_runner = join(os.environ['HOME'], 'bin/nextflow')
                subprocess.run(['mv', download_file, nf_runner])
                subprocess.run(['chmod', '+x', nf_runner])

        if which('nextflow') is None:
            print('Still can not find nextflow after attempted install. Aborting.')
            exit()
        spt.write_out_nextflow_script()
        subprocess.run(nextflow_invoker + [spt.nf_script_file])
