#!/usr/bin/env python

import argparse
import pycinema
import pycinema.filters
import yaml
import logging as log
import sys

# pycinema settings
PYCINEMA = { 'VERSION' : '3.2.0'}


def set_up_logging(args):
    # set up logging
        # turn off external logging
    log.getLogger("tensorflow").setLevel(log.WARNING)
    log.getLogger("PIL").setLevel(log.WARNING)
    log.getLogger("urllib3").setLevel(log.WARNING)
    log.getLogger("matplotlib").setLevel(log.WARNING)
    log.getLogger().setLevel(log.INFO)
    if args.verbose:
        log.getLogger().setLevel(log.DEBUG)

#
# execution of a script saved in theater application
#
def function_theater(args):
    import pycinema.theater
    set_up_logging(args)

    pycinema.theater.Theater(args.filenames)

#
# script included with pycinema
#
def function_browse(args):
    import pycinema.theater
    set_up_logging(args)

    args.filenames.insert(0, "browse")
    pycinema.theater.Theater(args.filenames)

#
# script included with pycinema
#
def function_discover(args):
    import pycinema.theater
    set_up_logging(args)

    args.filenames.insert(0, "discover")
    pycinema.theater.Theater(args.filenames)

#
# script included with pycinema
def function_explore(args):
    import pycinema.theater
    set_up_logging(args)

    args.filenames.insert(0, "explore")
    pycinema.theater.Theater(args.filenames)

#
# script included with pycinema
#
def function_imagegrid(args):
    import pycinema.theater
    set_up_logging(args)

    args.filenames.insert(0, "imagegrid")
    pycinema.theater.Theater(args.filenames)

#
# script included with pycinema
#
def function_view(args):
    import pycinema.theater
    set_up_logging(args)

    args.filenames.insert(0, "view")
    pycinema.theater.Theater(args.filenames)

#
# composite a database of HDF5 images into a database of png files
#
def function_compose(args):
    if args.debug:
        # enable debug output (e.g., timings)
        pycinema.Filter._debug = True

    if args.config:
        # load the config
        with open(args.config, 'r') as file:
            configdata = yaml.safe_load(file)

        # create and execute a composite object
        composite = pycinema.scripts.compose.Composite(configdata)
        composite.update()

#
# recolor a database of HDF5 images into a database of png files
#
def function_recolor(args):
    if args.debug:
        # enable debug output (e.g., timings)
        pycinema.Filter._debug = True

    if args.config:
        # load the config
        with open(args.config, 'r') as file:
            configdata = yaml.safe_load(file)

        # create and execute a composite object
        recolor = pycinema.scripts.recolor.Recolor(configdata)
        recolor.update()


#
# query metadata from a database of HDF5 images 
#
def function_meta(args):
    if args.debug:
        # enable debug output (e.g., timings)
        pycinema.Filter._debug = True

    # read scalar image cdb manifest
    CinemaDatabaseReader_0 = pycinema.filters.CinemaDatabaseReader()
    CinemaDatabaseReader_0.inputs.path.set(args.source, False)
    CinemaDatabaseReader_0.inputs.file_column.set(args.filecolumn, False)

    # read actual images
    ImageReader_0 = pycinema.filters.ImageReader()
    ImageReader_0.inputs.table.set(CinemaDatabaseReader_0.outputs.table, False)
    ImageReader_0.inputs.file_column.set(args.filecolumn, False)
    ImageReader_0.inputs.cache.set(True, False)

    # execute pipeline
    CinemaDatabaseReader_0.update()

    # do the work
    images = ImageReader_0.outputs.images.get()
    meta = images[0].meta
    # resolution = [int(meta['resolution'][0]), int(meta['resolution'][1])]
    print("image metadata")
    print("  format: hdf5")
    # print("  res   : " + ", ".join(map(str, resolution)))
    print("channels: ")
    print("  number: " + str(len(images[0].channels)))
    names = []
    for channel in images[0].channels:
        names.append(channel)

    print("  names : " + ", ".join(names))

#
# set up parsers
#
parser = argparse.ArgumentParser(description="Cinema  command line tool")
subparsers = parser.add_subparsers(dest='command', help='Sub-commands', required=False)

# Subparser for recolor
parser_recolor = subparsers.add_parser('recolor', help='recolor Cinema (hdf5) images to .png')
parser_recolor.add_argument('--debug', action='store_true', help='set debug mode')
parser_recolor.add_argument('config', help='define the configuration file')
parser_recolor.set_defaults(func=function_recolor)

# Subparser for compose
parser_compose = subparsers.add_parser('compose', help='convert Cinema (hdf5) images to .png')
parser_compose.add_argument('--debug', action='store_true', help='set debug mode')
parser_compose.add_argument('config', help='define the configuration file')
parser_compose.set_defaults(func=function_compose)

# Subparser for command 'meta'
parser_meta = subparsers.add_parser('meta', help='dump descriptive metadata about a cinema database (rgb and hdf5)')
parser_meta.add_argument('--debug', action='store_true', help='set debug mode')
parser_meta.add_argument('--filecolumn', default="FILE", help='define FILE column name')
parser_meta.add_argument('-v', '--verbose', action='store_true', help='enable verbose output')
parser_meta.add_argument('source', help='source cinema database')
parser_meta.set_defaults(func=function_meta)

# Subparser for viewers
parser_browse = subparsers.add_parser('browse', help='view a cinema database with \'browse\' app (rgb)')
parser_browse.add_argument( "-v", "--verbose", action="store_true" )
parser_browse.add_argument( "filenames", nargs='*' )
parser_browse.set_defaults(func=function_browse)
parser_discover = subparsers.add_parser('discover', help='view a cinema database with \'discover\' app (rgb)')
parser_discover.add_argument( "-v", "--verbose", action="store_true" )
parser_discover.add_argument( "filenames", nargs='*' )
parser_discover.set_defaults(func=function_discover)
parser_explore = subparsers.add_parser('explore', help='view a cinema database wth \'explore\' app (hdf5 and rgb)')
parser_explore.add_argument( "-v", "--verbose", action="store_true" )
parser_explore.add_argument( "filenames", nargs='*' )
parser_explore.set_defaults(func=function_explore)
parser_imagegrid = subparsers.add_parser('imagegrid', help='view a cinema database with \'imagegrid\' app (rgb)')
parser_imagegrid.add_argument( "-v", "--verbose", action="store_true" )
parser_imagegrid.add_argument( "filenames", nargs='*' )
parser_imagegrid.set_defaults(func=function_imagegrid)
parser_view = subparsers.add_parser('view', help='view a cinema database with \'view\' app (hdf5 and rgb)')
parser_view.add_argument( "-v", "--verbose", action="store_true" )
parser_view.add_argument( "filenames", nargs='*' )
parser_view.set_defaults(func=function_view)

# run a script
parser_theater = subparsers.add_parser('theater', help='run a cinema script in theater')
parser_theater.add_argument( "-v", "--verbose", action="store_true" )
parser_theater.add_argument( "filenames", nargs='*' )
parser_theater.set_defaults(func=function_theater)

# special cases
if len(sys.argv) == 1:
    sys.argv.append("theater")
elif len(sys.argv) > 1 and sys.argv[1].endswith(".py"):
    sys.argv.insert(1, "theater")

# parse and call subcommand arguments
args = parser.parse_args()

# Call the appropriate function based on the subcommand
if args.command:
    args.func(args)
else:
    parser.print_help()
