# -*- 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:
"""The ants module provides basic functions for interfacing with ANTS tools."""
from __future__ import print_function, division, unicode_literals, absolute_import
from builtins import str
# Local imports
from ... import logging
from ..base import CommandLine, CommandLineInputSpec, traits, isdefined
logger = logging.getLogger('interface')

# -Using -1 gives primary responsibilty to ITKv4 to do the correct
#  thread limitings.
# -Using 1 takes a very conservative approach to avoid overloading
#  the computer (when running MultiProc) by forcing everything to
#  single threaded.  This can be a severe penalty for registration
#  performance.
LOCAL_DEFAULT_NUMBER_OF_THREADS = 1
# -Using NSLOTS has the same behavior as ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS
#  as long as ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS is not set.  Otherwise
#  ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS takes precidence.
#  This behavior states that you the user explicitly specifies
#  num_threads, then respect that no matter what SGE tries to limit.
PREFERED_ITKv4_THREAD_LIMIT_VARIABLE = 'NSLOTS'
ALT_ITKv4_THREAD_LIMIT_VARIABLE = 'ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS'


class ANTSCommandInputSpec(CommandLineInputSpec):
    """Base Input Specification for all ANTS Commands
    """

    num_threads = traits.Int(LOCAL_DEFAULT_NUMBER_OF_THREADS, usedefault=True,
                             nohash=True, desc="Number of ITK threads to use")


class ANTSCommand(CommandLine):
    """Base class for ANTS interfaces
    """

    input_spec = ANTSCommandInputSpec
    _num_threads = LOCAL_DEFAULT_NUMBER_OF_THREADS

    def __init__(self, **inputs):
        super(ANTSCommand, self).__init__(**inputs)
        self.inputs.on_trait_change(self._num_threads_update, 'num_threads')

        if not isdefined(self.inputs.num_threads):
            self.inputs.num_threads = self._num_threads
        else:
            self._num_threads_update()

    def _num_threads_update(self):
        self._num_threads = self.inputs.num_threads
        # ONLY SET THE ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS if requested
        # by the end user.  The default setting did not allow for
        # overwriting the default values.
        # In ITKv4 (the version used for all ANTS programs), ITK respects
        # the SGE controlled $NSLOTS environmental variable.
        # If user specifies -1, then that indicates that the system
        # default behavior should be the one specified by ITKv4 rules
        # (i.e. respect SGE $NSLOTS or environmental variables of threads, or
        # user environmental settings)
        if (self.inputs.num_threads == -1):
            if (ALT_ITKv4_THREAD_LIMIT_VARIABLE in self.inputs.environ):
                del self.inputs.environ[ALT_ITKv4_THREAD_LIMIT_VARIABLE]
            if (PREFERED_ITKv4_THREAD_LIMIT_VARIABLE in self.inputs.environ):
                del self.inputs.environ[PREFERED_ITKv4_THREAD_LIMIT_VARIABLE]
        else:
            self.inputs.environ.update({PREFERED_ITKv4_THREAD_LIMIT_VARIABLE:
                                        '%s' % self.inputs.num_threads})

    @staticmethod
    def _format_xarray(val):
        """ Convenience method for converting input arrays [1,2,3] to commandline format '1x2x3' """
        return 'x'.join([str(x) for x in val])

    @classmethod
    def set_default_num_threads(cls, num_threads):
        """Set the default number of threads for ITK calls

        This method is used to set the default number of ITK threads for all
        the ANTS interfaces. However, setting this will not update the output
        type for any existing instances.  For these, assign the
        <instance>.inputs.num_threads
        """
        cls._num_threads = num_threads

@@ -319,16 +319,46 @@
 ort str%0A
+%0Aimport os%0Aimport subprocess%0A%0A
 # Local 
@@ -388,16 +388,30 @@
  logging
+, LooseVersion
 %0Afrom ..
@@ -1321,16 +1321,807 @@
 EADS'%0A%0A%0A
+class Info(object):%0A    _version = None%0A%0A    @property%0A    def version(self):%0A        if self._version is None:%0A            try:%0A                basedir = os.environ%5B'ANTSPATH'%5D%0A            except KeyError:%0A                return None%0A%0A            cmd = os.path.join(basedir, 'antsRegistration')%0A            try:%0A                res = subprocess.check_output(%5Bcmd, '--version'%5D).decode('utf-8')%0A            except OSError:%0A                return None%0A%0A            v_string = res.splitlines()%5B0%5D.split(': ')%5B1%5D%0A            # 2.2.0-equivalent version string%0A            if LooseVersion(v_string) %3E= LooseVersion('2.1.0.post789-g0740f'):%0A                self._version = '2.2.0'%0A            else:%0A                self._version = '.'.join(v_string.split('.')%5B:3%5D)%0A%0A        return self._version%0A%0A%0A
 class AN
@@ -4669,20 +4669,88 @@
 reads = num_threads%0A
+%0A    @property%0A    def version(self):%0A        return Info().version%0A

Add AntsCommand.version property