""" Command line module of h5cross"""

import click
import h5cross

# not to be used aside of the CLI
__all__ = []

@click.group()
def main_cli():
    """---------------    H5CROSS  --------------------

You are now using the Command line interface of h5cross
a Python3 helper to explore and compare hdf5 files, created at CERFACS (https://cerfacs.fr).


This is a python package currently installed in your python environement.
"""


@click.command()
@click.argument("filename", nargs=1)
def tree(filename):
    """Print the content of an hdf5 file in terminal.

    """
    from h5cross.visit_h5 import print_h5_structure
    
    print_h5_structure(filename)

main_cli.add_command(tree)


# NOTE: QUICK COMMANDS: e.g. @click.option('--out-name', '-n', 
# -n will be shortcut for --out-name
# -i  for out-indent 


@click.command()
@click.argument("filename", nargs=1)
@click.option('--out-name', required=False, default=None, type=str,
    help='default = None , if specified used as YAML output name. \
                            If not specified output name = filename.yml')
@click.option('--out-indent', required=False, default=2, type=int,
    help ='default = 2, sets the indentation level in ouput YAML file')
def dump(filename, out_name, out_indent):
    """Write the content of an hdf5 file into a YAML file.

    """
    from h5cross.view_h5 import get_h5_structure
    mydict = get_h5_structure(filename)

    if out_name is not None:
        writename = out_name
    else:
        writename = filename.split('.')[0]

    configure_yaml_output(mydict,writename, out_indent)

main_cli.add_command(dump)


@click.command()
@click.argument("filename", nargs=1)
def view(filename):
    """Show the content of an hdf5 file interactively with nobvisual.

    """

    from h5cross.view_h5 import visual_h5

    try:
        visual_h5(filename)
    except ImportError as excep:
        print("'h5cross view' stopped:", excep)
main_cli.add_command(view)


@click.command()
@click.argument("filename", nargs=1)
@click.option('--print-to-console', required=False, default=True, type=bool,
    help='default = True')
@click.option('--pretty-table', required=False, default=True, type=bool,
    help='default = True, controls if pretty table output is selected')
@click.option('--pretty-full-path', required=False, default=True, type=bool,
    help='default = True, controls if full paths in nested dictionary are output in pretty table')          
@click.option('--save-as-yaml', required=False, default=False, type=bool,
    help='default = False , if True: default output name is set to input file name')
@click.option('--out-name-yaml', required=False, default=None, type=str,
    help= 'default = None, if specified used as output name of YAML file')
@click.option('--out-indent', required=False, default=2, type=int,
    help ='default = 2, sets the indentation level in ouput YAML file')
# @click.option('--save-as-h5', required=False, default=False, type=bool,
#                     help='To be implemented')
# @click.option('--out-name-h5', required=False, default=None, type=str,
#                     help='To be implemented')
def stats(filename, print_to_console, pretty_table, pretty_full_path, save_as_yaml, out_name_yaml, out_indent):
#            save_as_h5, out_name_h5):
    """Compute statistics of arrays from hdf5 file.

    """
    
    from h5cross.visit_h5 import (get_h5_structure,
                                    get_h5_field,
                                    pretty_table_h5_stats,
                                    print_h5_structure)

    from h5cross.tools import add_numpy_statistics

    mydict = get_h5_structure(filename)
    myfield_dict = get_h5_field(filename)

    add_numpy_statistics(mydict, myfield_dict)
    if print_to_console:
        if pretty_table:
            try:
                pretty_table_h5_stats(mydict, full_path = pretty_full_path)
            except ImportError as excep:
                print("'h5cross stats' stopped:", excep)
        else:
            print_h5_structure(mydict)

    if save_as_yaml:
        if out_name_yaml is not None:
            writename = out_name_yaml
        else:
            writename = filename.split('.')[0]

        configure_yaml_output(mydict, writename, out_indent)

    
    # TO DO: rethink the save_as-> should be in the flow file, so not logic in struct
    #if save_as_h5:
    #    print("Currently not implemented")
    #     if out_name_h5 is not None:
    #         writename = out_name_h5
    #     else:
    #         writename = filename.split('.')[0] + "_stats"

    #     h5cross.write_h5(mydict,save_name = writename)

main_cli.add_command(stats)


@click.command()
@click.argument("file_left", nargs=1)
@click.argument("file_right", nargs=1)
@click.option('--add-stats', required=False, default=False, type=bool,
     help='default = False, if True will compute statistics for each file before comparing')
def diff(file_left, file_right, add_stats):
    """Compare the content of two hdf5 files and view interactively with nobvisual.

    """

    from h5cross.view_h5 import compare_h5

    try:
        compare_h5(file_left, file_right, add_stats)
    except ImportError as excep:
        print("'h5cross diff' stopped:", excep)
        return

main_cli.add_command(diff)

@click.command()
@click.argument("file_left", nargs=1)
@click.argument("file_right", nargs=1)
@click.option('--select-vars', required=True, default=None, type=str,
    help='default = None, select variables to plot. Requires a comma separated string with \
            variables to select, e.g. \"temperature,pressure\" ')
@click.option('--save-output', required=False, default=False, type=bool,
    help='default = False, if True will save the outputs of the plot(s)')
@click.option('--save-name', required=False, default=None, type=str,
    help='default = None, string specifying desired output base name for each plot')
@click.option('--show-output', required=False, default=True, type=bool,
    help='default = True, controls whether plot(s) are shown or not')
@click.option('--use-seaborn', required=False, default=True, type=bool,
    help='default = True, controls the use of seaborn. If False, matplotlib.pyplot is used.')
# @click.option('--add-xy', required=False, default=False, type=bool,
#     help='default = False, If True, superimposes the x=y line on the scatter plot.')
@click.option('--add-xy', required=False, is_flag=True,
    help='flag, if activated: superimposes the x=y line on the scatter plot.')



def scatter(file_left, file_right, select_vars,
            save_output, save_name,
            show_output, use_seaborn,
            add_xy):
    """ Scatter plot comparison of two hdf5 files.
        Seaborn is used to generate the plots but can
        be deactivated in which case matplotlib.pyplot is used.

        Note: The matplotlib package is a minimal requirement for this functionality.

    """
    from h5cross.view_h5 import compare_scatter_h5

    var_list = select_vars.split(",")
    try:
        compare_scatter_h5(file_left, file_right, var_list,
                flag_save=save_output, save_name=save_name,
                flag_show=show_output, flag_seaborn= use_seaborn,
                flag_xy_line = add_xy)
    except ImportError as excep:
        print("'h5cross scatter' stopped:", excep)
        return

main_cli.add_command(scatter)


@click.command()
@click.option('--array-length', required=False, default=None, type=int,
    help='default = None, controls the length of the data arrays')
@click.option('--out-name-h5', required=False, default=None, type=str,
    help='Optional output name for hdf5 file, default = dump.h5')
@click.option('--out-location-h5', required=False, default=None, type=str,
    help='Optional path where to save the hdf5 file, default = current dir')

def generate(array_length, out_name_h5, out_location_h5):
    """ Generates an hdf5 file from a random nested dictionary (also generated).
        It allows an easy input to test the other functionalities.
    """
    from h5cross.generate_h5 import generate_random_nested_dictionary
    from h5cross.write_h5 import write_h5

    # Todo: remove unnecessary elses
    if array_length:
        tmp_dict = generate_random_nested_dictionary(array_length=array_length)
    else:
        tmp_dict = generate_random_nested_dictionary()

    if out_name_h5 is not None:
        if out_location_h5 is not None:
            write_h5(tmp_dict, save_name_ = out_name_h5, save_path_= out_location_h5)
        else:
            write_h5(tmp_dict, save_name_ = out_name_h5)
    else:
        if out_location_h5 is not None:
            write_h5(tmp_dict, save_path_= out_location_h5)
        else:
            write_h5(tmp_dict)


main_cli.add_command(generate)


@click.command()
@click.argument("filename", nargs=1)
@click.option('--file-type', required=True, type=click.Choice(['nek5000','pvtu','vtu','vtk']), default=None,
    help='default = None, input format to convert to hdf5')
@click.option('--out-name-h5', required=False, default=None, type=str,
    help='Optional output name for hdf5 file, default = dump.h5')
@click.option('--out-location-h5', required=False, default=None, type=str,
    help='Optional path where to save the hdf5 file, default = current dir')

def convert(filename,file_type, out_name_h5, out_location_h5):
    """ Conversion to hdf5 of certain file formats. 
        Currently supported:
            - nek5000: requires "pymech" package
            - vtk: pvtu, vtu   requires "vtk" package
    """

    from h5cross.convert_h5 import convert_nek5000, convert_vtu, convert_vtk
    from h5cross.write_h5 import write_h5

    tmp_dict = dict()
    try:
        if file_type == "nek5000":
            tmp_dict = convert_nek5000(filename)
        elif file_type == "pvtu":
            tmp_dict = convert_vtu(filename, parallel_ = True)
        elif file_type == "vtu":
            tmp_dict = convert_vtu(filename, parallel_ = False)
        elif file_type == "vtk":
            tmp_dict = convert_vtk(filename)
    except ImportError as excep:
        print("'h5cross convert' stopped:", excep)
        return
    except AssertionError as excep:
        print("'h5cross convert' stopped:", excep)
        return
    except ValueError as excep:
        print("'h5cross convert' stopped:", excep)
        return

    if out_name_h5 is not None:
        if out_location_h5 is not None:
            write_h5(tmp_dict, save_name_ = out_name_h5, save_path_ = out_location_h5)
        else:
            write_h5(tmp_dict, save_name_ = out_name_h5)
    else:
        if out_location_h5 is not None:
            write_h5(tmp_dict, save_path_= out_location_h5)
        else:
            write_h5(tmp_dict)


main_cli.add_command(convert)


#----------------------extra functionalities------------------------#
def configure_yaml_output(dict_, out_name_, indent_):
    """ Function to set output options and write the yaml output

        Input:
            :dict_: dictionary to write out as a yaml file
            :out_name_: dtype = string, name of output yaml file
            :indent_: dtype = int, indentation level for output
        Output:
            writes a yaml file in current directory
    """

    from h5cross.write_h5 import write_dict_to_yaml
    if indent_ is None:
        indent_ = 2
    write_dict_to_yaml(dict_, out_name_, setindent=indent_)
