#!/usr/bin/env python3
#
# (c) 2020 Fetal-Neonatal Neuroimaging & Developmental Science Center
#                   Boston Children's Hospital
#
#              http://childrenshospital.org/FNNDSC/
#                        dev@babyMRI.org
#

import sys, os
sys.path.insert(1, os.path.join(os.path.dirname(__file__), '../pfdo_med2image'))

import  pfdo_med2image
from    argparse            import RawTextHelpFormatter
from    argparse            import ArgumentParser
import  pudb

import  pfmisc
from    pfmisc._colors      import Colors
from    pfmisc              import other

str_version = "1.0.0"
str_desc = Colors.CYAN + """

        __    _                           _  _____  _                             
       / _|  | |                         | |/ __  \(_)                            
 _ __ | |_ __| | ___   _ __ ___   ___  __| |`' / /' _ _ __ ___   __ _  __ _  ___  
| '_ \|  _/ _` |/ _ \ | '_ ` _ \ / _ \/ _` |  / /  | | '_ ` _ \ / _` |/ _` |/ _ \ 
| |_) | || (_| | (_) || | | | | |  __/ (_| |./ /___| | | | | | | (_| | (_| |  __/ 
| .__/|_| \__,_|\___/ |_| |_| |_|\___|\__,_|\_____/|_|_| |_| |_|\__,_|\__, |\___| 
| |               ______                                               __/ |      
|_|              |______|                                             |___/       



                          Path-File Do med2image

        Recursively walk down a directory tree and perform a 'med2image'
        on files in each directory (optionally filtered by some simple
        expression). Results of each operation are saved in output tree
        that  preserves the input directory structure.


                             -- version """ + \
             Colors.YELLOW + str_version + Colors.CYAN + """ --

        'pfdo_med2image' demonstrates how to use ``pftree`` to transverse
        directory trees and execute a ``med2image`` analysis at each directory
        level (that optionally contains files of interest).

        As part of the "pf*" suite of applications, it is geared to IO as
        directories. Nested directory trees within some input directory
        are reconstructed in an output directory, preserving directory
        structure.


""" + Colors.NO_COLOUR

def synopsis(ab_shortOnly = False):
    scriptName = os.path.basename(sys.argv[0])
    shortSynopsis =  """
    NAME

	    pfdo_med2image

    SYNOPSIS

        pfdo_med2image                                      \\
                     -I|--inputDir <inputDir>               \\
                     -O|--outputDir <outputDir>             \\
                    [-i|--inputFile <inputFile>]            \\
                    [--filterExpression <someFilter>]       \\
                    [--outputLeafDir <outputLeafDirFormat>] \\
                    [-t|--outputFileType <outputFileType>]  \\
                    [-s|--sliceToConvert <sliceToConvert>]  \\
                    [-f|--frameToConvert <frameToConvert>]  \\
                    [--showSlices]                          \\
                    [--func <functionName>]                 \\
                    [--reslice]                             \\
                    [--threads <numThreads>]                \\
                    [--test]                                \\
                    [-x|--man]                              \\
                    [-y|--synopsis]                         \\
                    [--followLinks]                         \\
                    [--json]

    BRIEF EXAMPLE

        pfdo_med2image                                      \\
            -I /var/www/html/data --filter nii              \\
            -O /var/www/html/jpg                            \\
            -t jpg                                          \\
            --threads 0 --printElapsedTime
    """

    description =  '''
    DESCRIPTION

        ``pfdo_med2image`` runs ``med2image`` at each path/file location in an
        input tree. The CLI space is the union of ``pfdo`` and ``med2image``.

    ARGS

        -I|--inputDir <inputDir>
        Input base directory to traverse.

        -O|--outputDir <outputDir>
        The output root directory that will contain a tree structure identical
        to the input directory, and each "leaf" node will contain the analysis
        results.

        [-i|--inputFile <inputFile>]
        An optional <inputFile> specified relative to the <inputDir>. If
        specified, then do not perform a directory walk, but convert only
        this file.

        [-f|--filterExpression <someFilter>]
        An optional string to filter the files of interest from the
        <inputDir> tree.

        [--outputLeafDir <outputLeafDirFormat>]
        If specified, will apply the <outputLeafDirFormat> to the output
        directories containing data. This is useful to blanket describe
        final output directories with some descriptive text, such as
        'anon' or 'preview'.

        This is a formatting spec, so

            --outputLeafDir 'preview-%%s'

        where %%s is the original leaf directory node, will prefix each
        final directory containing output with the text 'preview-' which
        can be useful in describing some features of the output set.

        [-o|--outputFileStem <outputFileStem>]
        The output file stem to store conversion. If this is specified
        with an extension, this extension will be used to specify the
        output file type.

        SPECIAL CASES:
        For DICOM data, the <outputFileStem> can be set to the value of
        an internal DICOM tag. The tag is specified by preceding the tag
        name with a percent character '%%', so

            -o %%ProtocolName

        will use the DICOM 'ProtocolName' to name the output file. Note
        that special characters (like spaces) in the DICOM value are
        replaced by underscores '_'.

        Multiple tags can be specified, for example

            -o %%PatientName%%PatientID%%ProtocolName

        and the output filename will have each DICOM tag string as
        specified in order, connected with dashes.

        [-t|--outputFileType <outputFileType>]
        The output file type. If different to <outputFileStem> extension,
        will override extension in favour of <outputFileType>.

        [-s|--sliceToConvert <sliceToConvert>]
        In the case of volume files, the slice (z) index to convert. Ignored
        for 2D input data. If a '-1' is sent, then convert *all* the slices.
        If an 'm' is specified, only convert the middle slice in an input
        volume.

        [-f|--frameToConvert <sliceToConvert>]
        In the case of 4D volume files, the volume (V) containing the
        slice (z) index to convert. Ignored for 3D input data. If a '-1' is
        sent, then convert *all* the frames. If an 'm' is specified, only
        convert the middle frame in the 4D input stack.

        [--showSlices]
        If specified, render/show image slices as they are created.

        [--func <functionName>]
        Apply the specified transformation function before saving. Currently
        support functions:

            * invertIntensities
              Inverts the contrast intensity of the source image.

        [--reslice]
        For 3D data only. Assuming [i,j,k] coordinates, the default is to save
        along the 'k' direction. By passing a --reslice image data in the 'i' and
        'j' directions are also saved. Furthermore, the <outputDir> is subdivided into
        'slice' (k), 'row' (i), and 'col' (j) subdirectories.

        [--threads <numThreads>]
        If specified, break the innermost analysis loop into <numThreads>
        threads.

        [-x|--man]
        Show full help.

        [-y|--synopsis]
        Show brief help.

        [--json]
        If specified, output a JSON dump of final return.

        [--followLinks]
        If specified, follow symbolic links.

        -v|--verbosity <level>
        Set the app verbosity level.

            0: No internal output;
            1: Run start / stop output notification;
            2: As with level '1' but with simpleProgress bar in 'pftree';
            3: As with level '2' but with list of input dirs/files in 'pftree';
            5: As with level '3' but with explicit file logging for
                    - read
                    - analyze
                    - write

    EXAMPLES

    Perform a `pfdo_med2image` down some input directory:

        pfdo_med2image                                      \\
            -I /var/www/html/data --filter nii              \\
            -O /var/www/html/jpg                            \\
            -t jpg                                          \\
            --threads 0 --printElapsedTime

    The above will find all files in the tree structure rooted at
    /var/www/html/data that also contain the string "nii" anywhere
    in the filename. For each file found, a `med2image` conversion
    will be called in the output directory, in the same tree location as
    the original input.

    Finally the elapsed time and a JSON output are printed.

    '''

    if ab_shortOnly:
        return shortSynopsis
    else:
        return shortSynopsis + description



parser  = ArgumentParser(description = str_desc, formatter_class = RawTextHelpFormatter)

parser.add_argument("-I", "--inputDir",
                    help    = "input dir",
                    dest    = 'inputDir')
parser.add_argument("-i", "--inputFile",
                    help    = "input file",
                    dest    = 'inputFile',
                    default = '')
parser.add_argument("--filterExpression",
                    help    = "string file filter",
                    dest    = 'filter',
                    default = '')
parser.add_argument("-O", "--outputDir",
                    help    = "output image directory",
                    dest    = 'outputDir',
                    default = '')
parser.add_argument("--printElapsedTime",
                    help    = "print program run time",
                    dest    = 'printElapsedTime',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--threads",
                    help    = "number of threads for innermost loop processing",
                    dest    = 'threads',
                    default = "0")
parser.add_argument("--outputLeafDir",
                    help    = "formatting spec for output leaf directory",
                    dest    = 'outputLeafDir',
                    default = "")
parser.add_argument("--test",
                    help    = "test",
                    dest    = 'test',
                    action  = 'store_true',
                    default = False)
parser.add_argument("-x", "--man",
                    help    = "man",
                    dest    = 'man',
                    action  = 'store_true',
                    default = False)
parser.add_argument("-y", "--synopsis",
                    help    = "short synopsis",
                    dest    = 'synopsis',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--json",
                    help    = "output final return in json",
                    dest    = 'json',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--overwrite",
                    help    = "overwrite files if already existing",
                    dest    = 'overwrite',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--followLinks",
                    help    = "follow symbolic links",
                    dest    = 'followLinks',
                    action  = 'store_true',
                    default = False)
parser.add_argument("-v", "--verbosity",
                    help    = "verbosity level for app",
                    dest    = 'verbosity',
                    default = "1")
parser.add_argument('--version',
                    help    = 'if specified, print version number',
                    dest    = 'b_version',
                    action  = 'store_true',
                    default = False)

# med2image additional CLI flags
parser.add_argument("-o", "--outputFileStem",
                    help    = "output file",
                    default = "output.jpg",
                    dest    = 'outputFileStem')
parser.add_argument("-t", "--outputFileType",
                    help    = "output image type",
                    dest    = 'outputFileType',
                    default = '')
parser.add_argument("-s", "--sliceToConvert",
                    help="slice to convert (for 3D data)",
                    dest='sliceToConvert',
                    default='-1')
parser.add_argument("-f", "--frameToConvert",
                    help    = "frame to convert (for 4D data)",
                    dest    = 'frameToConvert',
                    default = '-1')
parser.add_argument('-r', '--reslice',
                    help    = "save images along i,j,k directions -- 3D input only",
                    dest    = 'reslice',
                    action  = 'store_true',
                    default = False)
parser.add_argument('--showSlices',
                    help    = "show slices that are converted",
                    dest    = 'showSlices',
                    action  = 'store_true',
                    default = False)
parser.add_argument('--func',
                    help    = "apply transformation function before saving",
                    dest    = 'func',
                    default = "")



args = parser.parse_args()

if args.man or args.synopsis:
    print(str_desc)
    if args.man:
        str_help     = synopsis(False)
    else:
        str_help     = synopsis(True)
    print(str_help)
    sys.exit(1)

if args.b_version:
    print("Version: %s" % str_version)
    sys.exit(1)

args.str_version    = str_version
args.str_desc       = synopsis(True)

pf_do_med2image     = pfdo_med2image.pfdo_med2image(vars(args))

# And now run it!
# pudb.set_trace()
d_pfdo_med2image    = pf_do_med2image.run(timerStart = True)

if args.printElapsedTime:
    pf_do_med2image.dp.qprint(
            "Elapsed time = %f seconds" %
            d_pfdo_med2image['runTime']
    )

sys.exit(0)
