#!/usr/bin/env python3
#
# (c) 2017 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__), '../pftree'))

import  pftree
from    argparse            import RawTextHelpFormatter
from    argparse            import ArgumentParser
import  pudb

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

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


        __ _                 
       / _| |                
 _ __ | |_| |_ _ __ ___  ___ 
| '_ \|  _| __| '__/ _ \/ _ \\
| |_) | | | |_| | |  __/  __/
| .__/|_|  \__|_|  \___|\___|
| |                          
|_|                          

  

                        Path-File tree structure

        Recursively walk down an input directory tree and create a dictionary
        representation of the path structure. Each tree "key" has a list
        of files in that corresponding directory in the filesystem. 

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


""" + Colors.NO_COLOUR

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

	    %s - Create a dictionary representation of a filesystem tree.

    SYNOPSIS

            %s                                          \\
                    -I|--inputDir <inputDir>                \\
                    [-r|--relativeDir]                      \\
                    [-i|--inputFile <inputFile>]            \\
                    [-O|--outputDir <outputDir>]            \\
                    [--stats | --statsReverse]              \\
                    [-t|--threads <threads>]                \\
                    [--json]                                \\
                    [-x|--man]                              \\
                    [-y|--synopsis]

    BRIEF EXAMPLE

	    %s                                          \\
                    -I /var/www/html                        \\
                    -O /tmp                                 \\
                    -r                                      \\
                    --printElapsedTime                      \\
                    --stats -v -1 --json


    ''' % (scriptName, scriptName, scriptName)

    description =  '''
    DESCRIPTION

        `%s` in and of itself is does not really do any work. It is a
        class that provides the internals for representing file system
        hierarchies in dictionary form.

        Given an <inputDir>, pftree will perform a recursive walk down
        the directory tree. For each directory that contains files, 
        `pftree` will create a dictionary key of the directory path,
        and will store a list of filenames for the key value.

        The core the of the class is a <tree_analysisApply> method, that
        accepts various kwargs. When called, this method will loop
        over the dictionary, and for each key (i.e. 'path') will execute
        a callback method. This callback is passed the dictionary value
        at that key (i.e. usually just the list of files) as well as
        all the **kwargs passed to <tree_analysisApply>.

    ARGS

        -I|--inputDir <inputDir>
        Input DICOM directory to examine. By default, the first file in this
        directory is examined for its tag information. There is an implicit
        assumption that each <inputDir> contains a single DICOM series.

        [-r|--relativeDir]
        A flag argument. If passed (i.e. True), then the dictionary key values
        are taken to be relative to the <inputDir>, i.e. the key values
        will not contain the <inputDir>; otherwise the key values will
        contain the <inputDir>.

        [-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.

        [-O|--outputDir <outputDir>]
        The directory to contain all output files.

        [--stats | --statsReverse]
        If specified, return some stats to caller -- summary list ordered
        by directory size (--statsReverse does a reverse sort).

        [-t|--threads <numThreads>]
        If specified, break the innermost analysis loop into <numThreads>
        threads. Please note the following caveats:

            * Only thread if you have a high CPU analysis loop. Since
              most of the operations of this module will entail reading
              and writing DICOM files, and since these operations are 
              the bulk of the execution time, adding threading will not
              really help.

            * Threading will change the nature of the innermost looping
              across the problem domain, with the result that *all* of the
              problem data will be read into memory! That means all of 
              DICOMs across all of the subdirs! In non-threading mode,
              only DICOMs from a single directory at a time are read
              and then discarded.

        [--json]
        If specified, do a JSON dump of the stats.

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

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

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

             -1: No internal output.
              0: All internal output.

    EXAMPLES

        $ pftree            -I /var/www/html                \\
                            -O /tmp                         \\
                            -r                              \\
                            --printElapsedTime              \\
                            --stats -v -1 --json

        Use also a '-v 0' for more output.

    ''' % (scriptName)
    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',
                    default = '')
parser.add_argument("-i", "--inputFile",
                    help    = "input file",
                    dest    = 'inputFile',
                    default = '')
parser.add_argument("-O", "--outputDir",
                    help    = "output image directory",
                    dest    = 'outputDir',
                    default = '.')
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("-v", "--verbosity",
                    help    = "verbosity level for app",
                    dest    = 'verbosity',
                    default = "0")
parser.add_argument("-t", "--threads",
                    help    = "number of threads for innermost loop processing",
                    dest    = 'threads',
                    default = "0")
parser.add_argument("-r", "--relativeDir",
                    help    = "use relative directories",
                    dest    = 'relativeDir',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--stats",
                    help    = "show some quick stats",
                    dest    = 'stats',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--statsReverse",
                    help    = "show some quick stats (reverse order)",
                    dest    = 'statsReverse',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--json",
                    help    = "JSON dump stats",
                    dest    = 'json',
                    action  = 'store_true',
                    default = False)
parser.add_argument("--printElapsedTime",
                    help    = "print program run time",
                    dest    = 'printElapsedTime',
                    action  = 'store_true',
                    default = False)
parser.add_argument('--version',
                    help    = 'if specified, print version number',
                    dest    = 'b_version',
                    action  = 'store_true',
                    default = False)


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)

# pudb.set_trace()

pf_tree             = pftree.pftree(
                        inputDir            = args.inputDir,
                        inputFile           = args.inputFile,
                        outputDir           = args.outputDir,
                        relativeDir         = args.relativeDir,
                        stats               = args.stats,
                        statsReverse        = args.statsReverse,
                        threads             = args.threads,
                        json                = args.json,
                        verbosity           = args.verbosity
                    )

# And now run it!
other.tic()
pf_tree.run()
if args.printElapsedTime: pf_tree.dp.qprint("Elapsed time = %f seconds" % other.toc())
sys.exit(0)
