# -*- 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:
from __future__ import (print_function, division, unicode_literals,
                        absolute_import)
from builtins import open
import os
import os.path as op
import pytest
from nipype.testing.fixtures import (create_files_in_directory_plus_dummy_file,
                                     create_surf_file_in_directory)

from nipype.pipeline import engine as pe
from nipype.interfaces import freesurfer as fs
from nipype.interfaces.base import TraitError
from nipype.interfaces.io import FreeSurferSource


@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
def test_sample2surf(create_files_in_directory_plus_dummy_file):

    s2s = fs.SampleToSurface()
    # Test underlying command
    assert s2s.cmd == 'mri_vol2surf'

    # Test mandatory args exception
    with pytest.raises(ValueError):
        s2s.run()

    # Create testing files
    files, cwd = create_files_in_directory_plus_dummy_file

    # Test input settings
    s2s.inputs.source_file = files[0]
    s2s.inputs.reference_file = files[1]
    s2s.inputs.hemi = "lh"
    s2s.inputs.reg_file = files[2]
    s2s.inputs.sampling_range = .5
    s2s.inputs.sampling_units = "frac"
    s2s.inputs.sampling_method = "point"

    # Test a basic command line
    assert s2s.cmdline == (
        "mri_vol2surf "
        "--hemi lh --o %s --ref %s --reg reg.dat --projfrac 0.500 --mov %s" %
        (os.path.join(cwd, "lh.a.mgz"), files[1], files[0]))

    # Test identity
    s2sish = fs.SampleToSurface(
        source_file=files[1], reference_file=files[0], hemi="rh")
    assert s2s != s2sish

    # Test hits file name creation
    s2s.inputs.hits_file = True
    assert s2s._get_outfilename("hits_file") == os.path.join(
        cwd, "lh.a_hits.mgz")

    # Test that a 2-tuple range raises an error
    def set_illegal_range():
        s2s.inputs.sampling_range = (.2, .5)

    with pytest.raises(TraitError):
        set_illegal_range()


@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
def test_surfsmooth(create_surf_file_in_directory):

    smooth = fs.SurfaceSmooth()

    # Test underlying command
    assert smooth.cmd == "mri_surf2surf"

    # Test mandatory args exception
    with pytest.raises(ValueError):
        smooth.run()

    # Create testing files
    surf, cwd = create_surf_file_in_directory

    # Test input settings
    smooth.inputs.in_file = surf
    smooth.inputs.subject_id = "fsaverage"
    fwhm = 5
    smooth.inputs.fwhm = fwhm
    smooth.inputs.hemi = "lh"

    # Test the command line
    assert smooth.cmdline == \
        ("mri_surf2surf --cortex --fwhm 5.0000 --hemi lh --sval %s --tval %s/lh.a_smooth%d.nii --s fsaverage" %
         (surf, cwd, fwhm))

    # Test identity
    shmooth = fs.SurfaceSmooth(
        subject_id="fsaverage",
        fwhm=6,
        in_file=surf,
        hemi="lh",
        out_file="lh.a_smooth.nii")
    assert smooth != shmooth


@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
def test_surfxfm(create_surf_file_in_directory):

    xfm = fs.SurfaceTransform()

    # Test underlying command
    assert xfm.cmd == "mri_surf2surf"

    # Test mandatory args exception
    with pytest.raises(ValueError):
        xfm.run()

    # Create testing files
    surf, cwd = create_surf_file_in_directory

    # Test input settings
    xfm.inputs.source_file = surf
    xfm.inputs.source_subject = "my_subject"
    xfm.inputs.target_subject = "fsaverage"
    xfm.inputs.hemi = "lh"

    # Test the command line
    assert xfm.cmdline == \
        ("mri_surf2surf --hemi lh --tval %s/lh.a.fsaverage.nii --sval %s --srcsubject my_subject --trgsubject fsaverage" %
         (cwd, surf))

    # Test identity
    xfmish = fs.SurfaceTransform(
        source_subject="fsaverage",
        target_subject="my_subject",
        source_file=surf,
        hemi="lh")
    assert xfm != xfmish


@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
def test_surfshots(create_files_in_directory_plus_dummy_file):

    fotos = fs.SurfaceSnapshots()

    # Test underlying command
    assert fotos.cmd == "tksurfer"

    # Test mandatory args exception
    with pytest.raises(ValueError):
        fotos.run()

    # Create testing files
    files, cwd = create_files_in_directory_plus_dummy_file

    # Test input settins
    fotos.inputs.subject_id = "fsaverage"
    fotos.inputs.hemi = "lh"
    fotos.inputs.surface = "pial"

    # Test a basic command line
    assert fotos.cmdline == "tksurfer fsaverage lh pial -tcl snapshots.tcl"

    # Test identity
    schmotos = fs.SurfaceSnapshots(
        subject_id="mysubject", hemi="rh", surface="white")
    assert fotos != schmotos

    # Test that the tcl script gets written
    fotos._write_tcl_script()
    assert os.path.exists("snapshots.tcl")

    # Test that we can use a different tcl script
    foo = open("other.tcl", "w").close()
    fotos.inputs.tcl_script = "other.tcl"
    assert fotos.cmdline == "tksurfer fsaverage lh pial -tcl other.tcl"

    # Test that the interface crashes politely if graphics aren't enabled
    try:
        hold_display = os.environ["DISPLAY"]
        del os.environ["DISPLAY"]
        with pytest.raises(RuntimeError):
            fotos.run()
        os.environ["DISPLAY"] = hold_display
    except KeyError:
        pass


@pytest.mark.skipif(fs.no_freesurfer(), reason="freesurfer is not installed")
def test_mrisexpand(tmpdir):
    fssrc = FreeSurferSource(
        subjects_dir=fs.Info.subjectsdir(), subject_id='fsaverage', hemi='lh')

    fsavginfo = fssrc.run().outputs.get()

    # dt=60 to ensure very short runtime
    expand_if = fs.MRIsExpand(
        in_file=fsavginfo['smoothwm'], out_name='expandtmp', distance=1, dt=60)

    expand_nd = pe.Node(
        fs.MRIsExpand(
            in_file=fsavginfo['smoothwm'],
            out_name='expandtmp',
            distance=1,
            dt=60),
        name='expand_node')

    # Interfaces should have same command line at instantiation
    orig_cmdline = 'mris_expand -T 60 {} 1 expandtmp'.format(
        fsavginfo['smoothwm'])
    assert expand_if.cmdline == orig_cmdline
    assert expand_nd.interface.cmdline == orig_cmdline

    # Run Node interface
    nd_res = expand_nd.run()

    # Commandlines differ
    node_cmdline = 'mris_expand -T 60 -pial {cwd}/lh.pial {cwd}/lh.smoothwm ' \
        '1 expandtmp'.format(cwd=nd_res.runtime.cwd)
    assert nd_res.runtime.cmdline == node_cmdline

    # Check output
    if_out_file = expand_if._list_outputs()['out_file']
    nd_out_file = nd_res.outputs.get()['out_file']
    # Same filename
    assert op.basename(if_out_file) == op.basename(nd_out_file)
    # Interface places output in source directory
    assert op.dirname(if_out_file) == op.dirname(fsavginfo['smoothwm'])
    # Node places output in working directory
    assert op.dirname(nd_out_file) == nd_res.runtime.cwd
