#!/usr/bin/env python

# Generates a HTML page from the .csv files
# the files are output from the classifiers
import argparse
import logging

from common.configuration import ConfigurationHandler
from common.workspace import WorkspaceHandler
import pandas as pd
import gc

#
#   Handling the logging; now it logs to console
#   to change that to a file, change the stream handler
#
logger = logging.getLogger('pyccflex')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
logger.addHandler(ch)

if __name__ == '__main__':

    logger.info("\n#### Running: {}".format(__file__))

    logger.info(">>> Starting HTML export: ")

    #
    #   Parsing parameters from the files
    #

    parser = argparse.ArgumentParser()
    parser.add_argument("--locations_config", help="Path to locations configuration file",
                        type=str, required=False, default="./locations.json")
    parser.add_argument("--files_format_config", help="Path to files format configuration file",
                        type=str, required=False, default="./files_format.json")
    parser.add_argument("input_csv",
                        help="Path to input csv file", type=str)
    parser.add_argument("output_html",
                        help="Path to output html file", type=str)
    parser.add_argument("--all", help="Include all columns in html output",
                        default=False, action='store_true')
    parser.add_argument("--split_files", help="Generate a separate file for each chunk of lines (chunk_size)",
                        default=False, action='store_true')
    parser.add_argument("--chunk_size", help="Number of lines to process in a batch",
                        type=int, required=False, default=10 ** 5)
    args = vars(parser.parse_args())
    logger.info("Run parameters: {}".format(str(args)))

    locations_file_path = args['locations_config']
    files_format_file_path = args['files_format_config']
    all_columns = args['all']
    chunk_size = args['chunk_size']
    split_files = args['split_files']

    logger.info(">>>> Setting up paths complete!")

    try:
        locations_config = ConfigurationHandler(locations_file_path)
    except Exception as e:
        logger.error("Couldn't load configuration file {}".format(locations_file_path))
        exit(1)

    try:
        files_format_config = ConfigurationHandler(files_format_file_path)
    except Exception as e:
        logger.error("Couldn't load configuration file {}".format(files_format_file_path))
        exit(1)

    workspace_dir_conf = locations_config.get('workspace_dir', None)
    workspace_dir_path = workspace_dir_conf.get("path", "")
    workspace_dir = WorkspaceHandler(workspace_dir_path)

    input_file = workspace_dir.get_file_path(args['input_csv'])

    output_file = workspace_dir.get_reports_file_path(args['output_html'])

    # read the csv file
    df_chunks = pd.read_csv(input_file, sep=files_format_config.get("csv_sep", ","), encoding="utf-8",
                            chunksize=chunk_size)

    if split_files:
        for i, df in enumerate(df_chunks):

            if df.shape[0] > 0:
                if 'contents' in list(df.columns):
                    df.contents = df.contents.fillna("")

                # get the names of the columns
                column_names = df.iloc[0]
                df.rename(columns=column_names)

                # printing to HTML
                if not all_columns:
                    html_string = df[['id', 'contents', 'class_name']].to_html()
                else:
                    html_string = df.to_html()

                html_string = html_string.encode(encoding='UTF-8', errors='ignore')

                # and now printing to file
                chunk_output_file = workspace_dir.get_reports_file_path(
                    "{}-{}.html".format("".join(args['output_html'].split(".")[:-1]), i))
                with open(chunk_output_file, 'wb') as output_html_file:
                    output_html_file.write(html_string)

                logger.info(">>> Saving {} lines to the file {}".format(df.shape[0], chunk_output_file))

                del df
                gc.collect()
    else:

        with open(output_file, 'wb') as output_html_file:
            for i, df in enumerate(df_chunks):
                if df.shape[0] > 0:
                    if 'contents' in list(df.columns):
                        df.contents = df.contents.fillna("")

                    # get the names of the columns
                    column_names = df.iloc[0]
                    df.rename(columns=column_names)

                    # printing to HTML
                    if not all_columns:
                        html_string = df[['id', 'contents', 'class_name']].to_html()
                    else:
                        html_string = df.to_html()

                    html_string = html_string.encode(encoding='UTF-8', errors='ignore')

                    # and now printing to file
                    output_html_file.write(html_string)

                    logger.info(">>> Saving {} lines to the file {}".format(df.shape[0], output_file))

                    del df
                    gc.collect()

    logger.info(">>> Export to HTML successful!")
