#! /usr/bin/env python3
# -*- coding: utf-8 -*-
##########################################################################
# NSAp - Copyright (C) CEA, 2021
# Distributed under the terms of the CeCILL-B license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
# for details.
##########################################################################


# System import
import os
import argparse
import textwrap
from pprint import pprint
from datetime import datetime
from argparse import RawTextHelpFormatter
import nibabel
import brainprep


# Script documentation
DOC = """
The quasi-raw preprocessing script.
"""


def is_file(filearg):
    """ Type for argparse - checks that file exists but does not open.
    """
    if not os.path.isfile(filearg):
        raise argparse.ArgumentError(
            "The file '{0}' does not exist!".format(filearg))
    return filearg


def is_directory(dirarg):
    """ Type for argparse - checks that directory exists.
    """
    if not os.path.isdir(dirarg):
        raise argparse.ArgumentError(
            "The directory '{0}' does not exist!".format(dirarg))
    return dirarg


def get_cmd_line_args():
    """
    Create a command line argument parser and return a dict mapping
    <argument name> -> <argument value>.
    """
    parser = argparse.ArgumentParser(
        prog="brainprep-quasiraw",
        description=textwrap.dedent(DOC),
        formatter_class=RawTextHelpFormatter)

    # Required arguments
    required = parser.add_argument_group("required arguments")
    required.add_argument(
        "-a", "--anatomical",
        required=True, metavar="<path>", type=is_file,
        help="path to the anatomical T1w Nifti file.")
    required.add_argument(
        "-m", "--mask",
        required=True, metavar="<path>", type=is_file,
        help="a binary mask to be applied.")
    required.add_argument(
        "-o", "--outdir",
        required=True, metavar="<path>", type=is_directory,
        help="the destination folder.")

    # Optional arguments
    parser.add_argument(
        "-T", "--target",
        metavar="<path>",
        help="a custom target image for the registration.")
    parser.add_argument(
        "-V", "--verbose",
        type=int, choices=[0, 1, 2], default=0,
        help="increase the verbosity level: 0 silent, [1, 2] verbose.")

    # Create a dict of arguments to pass to the 'main' function
    args = parser.parse_args()
    kwargs = vars(args)
    if kwargs["target"] is None:
        resource_dir = os.path.join(os.path.dirname(
            brainprep.__file__), "resources")
        kwargs["target"] = os.path.join(
            resource_dir, "MNI152_T1_1mm_brain.nii.gz")
    verbose = kwargs.pop("verbose")

    return kwargs, verbose


"""
Parse the command line.
"""
inputs, verbose = get_cmd_line_args()
runtime = {
    "tool": "brainprep-quasiraw",
    "timestamp": datetime.now().isoformat(),
    "tool_version": brainprep.__version__}
if verbose > 0:
    pprint("[info] Starting quasi-raw preprocessing...")
    pprint("[info] Runtime:")
    pprint(runtime)
    pprint("[info] Inputs:")
    pprint(inputs)


"""
Launch quasi-raw preprocessing
"""
imfile = inputs["anatomical"]
maskfile = inputs["mask"]
targetfile = inputs["target"]
outdir = inputs["outdir"]
basename = (
    os.path.basename(imfile).split(".")[0].replace("_T1w", "_desc-{0}_T1w"))
basefile = os.path.join(outdir, basename + ".nii.gz")
stdfile = basefile.format("1std")
stdmaskfile = braiainfilebasefile.format("1maskstd")
brainfile = basefile.format("2brain")
scaledfile = basefile.format("3scaled")
bfcfile = basefile.format("4bfc")
regfile = basefile.format("5reg")
regmaskfile = basefile.format("5maskreg")
applyfile = basefile.format("6apply")

brainprep.reorient2std(imfile, stdfile)
brainprep.reorient2std(maskfile, stdmaskfile)
brainprep.apply_mask(stdfile, stdmaskfile, brainfile)
brainprep.scale(brainfiles, scaledfile, scale=1)
brainprep.biasfield(scaledfile, bfcfile)
_, trffile = brainprep.register_affine(bfcfile, targetfile, regfile)
brainprep.apply_affine(stdmaskfile, regfile, regmaskfile, trffile,
                       interp="nearestneighbour")
brainprep.apply_mask(regfile, regmaskfile, applyfile)
