# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""This commandline module provides classes for interfacing with the
`ICA-AROMA.py<https://github.com/rhr-pruim/ICA-AROMA>`_ command line tool.
    Change directory to provide relative paths for doctests
    >>> import os
    >>> filepath = os.path.dirname(os.path.realpath(__file__))
    >>> datadir = os.path.realpath(os.path.join(filepath,
    ...                            '../../testing/data'))
    >>> os.chdir(datadir)
"""

from __future__ import print_function, division, unicode_literals, absolute_import
from ..base import (TraitedSpec, CommandLineInputSpec, CommandLine,
                    File, Directory, traits, isdefined)
import os


class ICA_AROMAInputSpec(CommandLineInputSpec):
    feat_dir = Directory(exists=True, mandatory=True,
                         argstr='-feat %s',
                         xor=['in_file', 'mat_file', 'fnirt_warp_file', 'motion_parameters'],
                         desc='If a feat directory exists and temporal filtering '
                         'has not been run yet, ICA_AROMA can use the files in '
                         'this directory.')
    in_file = File(exists=True, mandatory=True,
                   argstr='-i %s', xor=['feat_dir'],
                   desc='volume to be denoised')
    out_dir = Directory('out', genfile=True,
                        argstr='-o %s',
                        desc='output directory')
    mask = File(exists=True, argstr='-m %s', xor=['feat_dir'],
                desc='path/name volume mask')
    dim = traits.Int(argstr='-dim %d',
                     desc='Dimensionality reduction when running '
                     'MELODIC (defualt is automatic estimation)')
    TR = traits.Float(argstr='-tr %.3f',
                      desc='TR in seconds. If this is not specified '
                      'the TR will be extracted from the '
                      'header of the fMRI nifti file.')
    melodic_dir = Directory(exists=True, argstr='-meldir %s',
                            desc='path to MELODIC directory if MELODIC has already been run')
    mat_file = File(exists=True, argstr='-affmat %s', xor=['feat_dir'],
                    desc='path/name of the mat-file describing the '
                    'affine registration (e.g. FSL FLIRT) of the '
                    'functional data to structural space (.mat file)')
    fnirt_warp_file = File(exists=True, argstr='-warp %s', xor=['feat_dir'],
                           desc='File name of the warp-file describing '
                           'the non-linear registration (e.g. FSL FNIRT) '
                           'of the structural data to MNI152 space (.nii.gz)')
    motion_parameters = File(exists=True, mandatory=True,
                             argstr='-mc %s', xor=['feat_dir'],
                             desc='motion parameters file')
    denoise_type = traits.Enum('nonaggr', 'aggr', 'both', 'no', usedefault=True,
                               mandatory=True, argstr='-den %s',
                               desc='Type of denoising strategy:\n'
                               '-no: only classification, no denoising\n'
                               '-nonaggr (default): non-aggresssive denoising, i.e. partial component regression\n'
                               '-aggr: aggressive denoising, i.e. full component regression\n'
                               '-both: both aggressive and non-aggressive denoising (two outputs)')

class ICA_AROMAOutputSpec(TraitedSpec):
    aggr_denoised_file = File(exists=True,
                              desc='if generated: aggressively denoised volume')
    nonaggr_denoised_file = File(exists=True,
                                 desc='if generated: non aggressively denoised volume' )
    out_dir = Directory(exists=True,
                        desc='directory contains (in addition to the denoised files): '
                        'melodic.ica + classified_motion_components + '
                        'classification_overview + feature_scores + melodic_ic_mni)')

class ICA_AROMA(CommandLine):
    """
    Interface for the ICA_AROMA.py script.

    ICA-AROMA (i.e. 'ICA-based Automatic Removal Of Motion Artifacts') concerns
    a data-driven method to identify and remove motion-related independent
    components from fMRI data. To that end it exploits a small, but robust
    set of theoretically motivated features, preventing the need for classifier
    re-training and therefore providing direct and easy applicability.

    See link for further documentation: https://github.com/rhr-pruim/ICA-AROMA

    Example
    -------

    >>> from nipype.interfaces.fsl import ICA_AROMA
    >>> from nipype.testing import example_data
    >>> AROMA_obj = ICA_AROMA()
    >>> AROMA_obj.inputs.in_file = 'functional.nii'
    >>> AROMA_obj.inputs.mat_file = 'func_to_struct.mat'
    >>> AROMA_obj.inputs.fnirt_warp_file = 'warpfield.nii'
    >>> AROMA_obj.inputs.motion_parameters = 'fsl_mcflirt_movpar.txt'
    >>> AROMA_obj.inputs.mask = 'mask.nii.gz'
    >>> AROMA_obj.inputs.denoise_type = 'both'
    >>> AROMA_obj.inputs.out_dir = 'ICA_testout'
    >>> AROMA_obj.cmdline
    'ICA_AROMA.py -den both -warp warpfield.nii -i functional.nii -m mask.nii.gz -affmat func_to_struct.mat -mc fsl_mcflirt_movpar.txt -o ICA_testout'
    """
    _cmd = 'ICA_AROMA.py'
    input_spec = ICA_AROMAInputSpec
    output_spec = ICA_AROMAOutputSpec

    def _list_outputs(self):
        outputs = self.output_spec().get()
        if isdefined(self.inputs.out_dir):
            outputs['out_dir'] = os.path.abspath(self.inputs.out_dir)
        else:
            outputs['out_dir'] = self._gen_filename('out_dir')
        out_dir = outputs['out_dir']

        if self.inputs.denoise_type in ('aggr', 'both'):
            outputs['aggr_denoised_file'] = os.path.join(out_dir, 'denoised_func_data_aggr.nii.gz')
        if self.inputs.denoise_type in ('nonaggr', 'both'):
            outputs['nonaggr_denoised_file'] = os.path.join(out_dir, 'denoised_func_data_nonaggr.nii.gz')
        return outputs

    def _gen_filename(self, name):
        if name == 'out_dir':
            return os.getcwd()
