#!/usr/bin/env python
"""
Runs the `qipipe <http://qipipe.readthedocs.org/en/latest/>`_ pipeline.
"""

import sys
import os
import shutil
import imp
import argparse
from qiutil import command
from qipipe.helpers import logging


def main(argv=sys.argv):
    # Parse the command line arguments.
    inputs, opts = _parse_arguments()
    # Break out the logging options.
    log_opts = {k: opts.pop(k) for k in ['log', 'log_level'] if k in opts}
    # Configure the logger.
    logging.configure(**log_opts)

    # Import the qipipe pipeline module after configuring the logger
    # above, since importing any nipype module writes to the log.
    from qipipe.pipeline import qipipeline as qip

    # Set the distributable flag.
    if opts.pop('no_submit', None):
        opts['distributable'] = False

    # Run the QIN workflow.
    qip.run(*inputs, **opts)

    return 0


def _parse_arguments():
    """
    Parses the command line arguments.

    :return: the (inputs, options) tuple, where inputs is the non-option
        arguments and options is an {option: value} dictionary
    """
    parser = argparse.ArgumentParser()

    # The general options.
    command.add_options(parser)

    # The actions.
    parser.add_argument('--stage', dest='actions', action='append_const',
                        const='stage', help='stage the input DICOM files')
    parser.add_argument('--roi', dest='actions', action='append_const',
                        const='roi', help='generate the ROI mask files')
    parser.add_argument('--register', dest='actions', action='append_const',
                        const='register', help='register the scans')
    parser.add_argument('--model', dest='actions', action='append_const',
                        const='model', help='model the realigned images')

    # The workflow configurations directory.
    parser.add_argument('--config-dir', metavar='DIR',
                        help='the optional workflow configurations directory')

    # Flag indicating whether to prepare but not run the pipeline.
    parser.add_argument('--dry-run', action='store_true',
                        help='prepare but do not run the pipeline')

    # Flag indicating whether to curtail cluster job submission.
    parser.add_argument('--no-submit', action='store_true',
                        help="don't submit jobs to a cluster environment")

    ##
    # TODO -
    # * Move the staging, registration and modeling options to
    #   a config file with sections [Staging], etc.
    # * Add a -c/--config option, with default ./qipipe.cfg.
    # * Rename staging/ohsu.py to staging/patterns and read the
    #   constants from the config property file.
    ##
    # The staging options.
    parser.add_argument('-p', '--project',
                        help='the XNAT project name, required for staging')
    parser.add_argument('-c', '--collection',
                        help='the collection to stage, required for staging')
    parser.add_argument('--scan', help='the optional staging scan number',
                        type=int, metavar='SCAN')
    parser.add_argument('--resume', action='store_true',
                        help='resume staging on existing sessions'
                             ' (default False)')

    # The output and work options.
    parser.add_argument('-o', '--output',
                        help='the destination directory'
                             ' (default current directory)',
                        metavar='DIR', dest='dest')
    parser.add_argument('-w', '--work',
                        help='the work directory'
                             ' (default a new temp directory)',
                        metavar='DIR', dest='base_dir')

    # The registration options.
    parser.add_argument('--registration-resource',
                        help='the XNAT registration resource label',
                        metavar='RESOURCE')
    parser.add_argument('--registration-technique',
                        help='the XNAT registration technique'
                             ' (required for registration)',
                        metavar='TECHNIQUE')
    parser.add_argument('--recursive-registration',
                        help="perform step-wise iterative"
                             " recursive registration",
                        action='store_true')

    # The modeling options.
    parser.add_argument('--modeling-resource',
                        help='the XNAT modeling resource name',
                        metavar='RESOURCE')
    parser.add_argument('--modeling-technique',
                        help='the XNAT modeling technique'
                             ' (required for modeling)',
                        metavar='TECHNIQUE')

    # The input directories or XNAT labels to process.
    parser.add_argument('input', nargs='+',
                        help='the input session directory or XNAT object path'
                             ' to process')

    args = vars(parser.parse_args())
    nonempty_args = dict((k, v) for k, v in args.iteritems() if v != None)

    return nonempty_args.pop('input'), nonempty_args


if __name__ == '__main__':
    sys.exit(main())
