#!/usr/bin/env python2
import argparse
from collections import OrderedDict

import openpyxl #Excel spreadsheet manipulation library
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.worksheet.cell_range import CellRange
from openpyxl.cell.cell import TYPE_NUMERIC
import os
import pandas as pd
import re

DEFAULT_METRICS = [
    #ABC QoR Metrics
    'abc_depth',
    'num_pre_packed_blocks',

    #Pack QoR Metrics
    'num_post_packed_blocks',
    'num_clb', #VTR
    'num_memories', #VTR
    'num_mult', #VTR
    'num_LAB', #Titan
    'num_DSP', #Titan
    'num_M9K', #Titan
    'num_M144K', #Titan
    'device_grid_tiles',

    #Place QoR Metrics
    'placed_wirelength_est',
    'placed_CPD_est',

    #Route QoR Metrics
    'min_chan_width', #VTR
    'routed_wirelength', #VTR (minW), Titan
    'crit_path_routed_wirelength', #VTR
    'critical_path_delay', #VTR/Titan

    #Run-time Metrics
    'odin_synth_time',
    'abc_synth_time',
    'pack_time',
    'place_time',
    'min_chan_width_route_time',
    'crit_path_route_time',
    'vtr_flow_elapsed_time',
    'max_vpr_mem',
]

DEFAULT_KEYS = [
    'arch',
    'circuit',
]

def parse_args():

    parser = argparse.ArgumentParser(description="Utility script to generate spreadsheets comparing VTR metric files")

    parser.add_argument("parse_result_files",
                        nargs="*",
                        metavar="PARSE_RESULT.TXT",
                        help="Set of metric files to compare")

    parser.add_argument("--result_names",
                        nargs="+",
                        metavar="RESULT_NAME",
                        help="Name of for each metric file (default: derived from filenames)")

    parser.add_argument("-o", "--output_spreadsheet",
                        metavar="OUTPUT.XLSX",
                        default="comparison_output.xlsx",
                        help="Output spreadsheet file (default: %(default)s)")

    parser.add_argument("--qor_metrics",
                        nargs="+",
                        default=DEFAULT_METRICS,
                        help="QoR Metrics to compare (default: %(default)s)")

    parser.add_argument("--keys",
                        nargs="+",
                        default=DEFAULT_KEYS,
                        help="Default keys to identify individual experiments (default: %(default)s)")

    parser.add_argument("-t", "--task",
                        metavar="task_name",
                        default="",
                        help="Compare the latest result of a task to its golden results")

    args = parser.parse_args()

    if (args.task):
        args.parse_result_files = get_task_result_files(args.task)

    if (not args.task and len(args.parse_result_files) == 0):
        raise RuntimeError("No parse result files or task name provided")

    if not args.result_names or len(args.result_names) == 0:
        args.result_names = args.parse_result_files
    elif len(args.result_names) != len(args.parse_result_files):
        raise RuntimeError("Number of result names ({}) does not match number of result files ({})".format(len(args.result_names), len(args.parse_result_files)))
    else:
        assert len(args.result_names) == len(args.parse_result_files)

    return args

def main():

    args = parse_args()

    wb = openpyxl.Workbook()

    wb.remove(wb.active)

    assert len(args.result_names) == len(args.parse_result_files)

    avail_metrics = set()

    #Load all the raw data into separate sheets
    raw_sheets = OrderedDict()
    for i, csv in enumerate(args.parse_result_files):
        #Load as CSV
        print "Loading", csv
        df = pd.read_csv(csv, sep='\t')

        avail_metrics.update(df.columns) #Record available metrics

        #Convert to work sheet
        sheet_name = safe_sheet_title("{}".format(args.result_names[i]))
        ws = dataframe_to_sheet(wb, df, sheet_name)

        raw_sheets[sheet_name] = ws

    qor_metrics = []
    for metric in args.qor_metrics:
        if metric not in avail_metrics:
            print "Warning: Metric", metric, "not found in parse results (may be for a different benchmark set)"
        else:
            qor_metrics.append(metric)

    #Create sheet of ratios
    ratio_sheet = wb.create_sheet("ratios", index=0)
    ratio_ranges = make_ratios(ratio_sheet, raw_sheets, keys=args.keys, metrics=qor_metrics)

    #Create summary sheet
    summary_data_sheet = wb.create_sheet("summary_data", index=0)
    make_summary(summary_data_sheet, ratio_sheet, ratio_ranges, args.keys)

    summary_sheet = wb.create_sheet("summary", index=0)
    make_transpose(summary_sheet, summary_data_sheet)

    wb.save(args.output_spreadsheet)

def make_transpose(dest_sheet, ref_sheet):

    for ref_row in xrange(ref_sheet.min_row, ref_sheet.max_row + 1):
        for ref_col in xrange(ref_sheet.min_column, ref_sheet.max_column + 1):
            ref_cell = ref_sheet.cell(row=ref_row, column=ref_col)

            dest_cell = dest_sheet.cell(row=ref_col, column=ref_row)
            dest_cell.value = "=IF(OR(ISBLANK({cell}),ISERROR({cell})),\"\",{cell})".format(cell=value_ref(ref_cell))

def make_summary(summary_sheet, ratio_sheet, ratio_ranges, keys):
    dest_row = 1
    for i, (ratio_name, cell_range) in enumerate(ratio_ranges.iteritems()):

        dest_col = 1

        if i == 0: #First range, copy headers

            dest_col += 1
            ratio_row = cell_range.min_row
            for j, ratio_col in enumerate(xrange(cell_range.min_col, cell_range.max_col + 1)):
                ratio_cell = ratio_sheet.cell(row=ratio_row, column=ratio_col)

                if j < len(keys):
                    continue
                else:
                    dest_cell = summary_sheet.cell(row=dest_row, column=dest_col)
                    dest_cell.value = "={}".format(value_ref(ratio_cell))
                    dest_col += 1
            dest_row += 1
            dest_col = 1 #Reset for next row

        #
        #Data
        #

        #Ratio name
        dest_cell = summary_sheet.cell(row=dest_row, column=dest_col)
        dest_cell.value = ratio_name

        dest_col += 1

        #Ratio values
        ratio_row = cell_range.max_row #Geomean is in last row
        for ratio_col in xrange(cell_range.min_col + len(keys), cell_range.max_col + 1):
            ratio_cell = ratio_sheet.cell(row=ratio_row, column=ratio_col)

            dest_cell = summary_sheet.cell(row=dest_row, column=dest_col)
            dest_cell.value = "={}".format(value_ref(ratio_cell))

            dest_col += 1

        dest_row += 1

def make_ratios(ratio_sheet, raw_sheets, keys, metrics):

    ref_sheet_title = raw_sheets.keys()[0]

    ref_sheet = raw_sheets[ref_sheet_title] #Get the first raw sheet

    cell_ranges = OrderedDict()

    row = 1
    for raw_sheet_title, raw_sheet in raw_sheets.iteritems():
        ratio_subtitle = ratio_sheet.cell(row=row, column=1)
        ratio_subtitle.value = raw_sheet_title
        row += 1


        cell_range = fill_ratio(ratio_sheet, raw_sheet, ref_sheet, dest_row=row, dest_col=1, keys=keys, metrics=metrics)
        row += cell_range.max_row - cell_range.min_row
        row += 2

        cell_ranges[raw_sheet_title] = cell_range

    return cell_ranges

def fill_ratio(ws, raw_sheet, ref_sheet, dest_row, dest_col, keys, metrics):


    cell_range = CellRange(min_row=dest_row, max_row=dest_row,
                           min_col=dest_col, max_col=dest_col,
                           title=ws.title)


    link_sheet_header(ws, ref_sheet, row=dest_row, values=keys+metrics)
    dest_row += 1

    col_offset = 0
    for ref_col in xrange(1, ref_sheet.max_column + 1):
        ref_header = ref_sheet.cell(row=1, column=ref_col)
        raw_header = raw_sheet.cell(row=1, column=ref_col)

        ref_header_name = ref_header.value.strip()
        raw_header_name = ref_header.value.strip()
        assert ref_header_name == raw_header_name, "Header values must match"

        if ref_header_name not in keys + metrics:
            continue

        row_offset = 0
        for ref_row in xrange(2, ref_sheet.max_row + 1):

            ref_cell = ref_sheet.cell(row=ref_row, column=ref_col)
            raw_cell = raw_sheet.cell(row=ref_row, column=ref_col)

            dest_cell = ws.cell(row=dest_row + row_offset, column=dest_col + col_offset)


            if ref_header_name in keys:
                assert ref_cell.value == raw_cell.value, "Key value must match"

                dest_cell.value = "={}".format(value_ref(ref_cell))
            elif ref_header.value in metrics and ref_cell.data_type == TYPE_NUMERIC:
                dest_cell.value = "={}".format(safe_ratio_ref(raw_cell, ref_cell))
            else:
                pass
                #assert False
            row_offset += 1

        #Last row: Add GEOMEAN
        dest_cell = ws.cell(row=dest_row + row_offset, column=dest_col + col_offset)
        if ref_header.value in keys:
            if keys.index(ref_header.value) == len(keys) - 1:
                #Last key make geomean title
                dest_cell.value = "GEOMEAN"
        else:
            start_cell = ws.cell(row=dest_row + row_offset - ref_sheet.max_row + 1, column=dest_col + col_offset)
            end_cell = ws.cell(row=dest_row + row_offset - 1, column=dest_col + col_offset)

            dest_cell.value = "=GEOMEAN({}:{})".format(start_cell.coordinate, end_cell.coordinate)

        row_offset += 1
        col_offset += 1

    cell_range.expand(down=row_offset, right=col_offset-1)

    return cell_range

def value_ref(cell):
    return "{}!{}".format(cell.parent.title, cell.coordinate)

def ratio_ref(num_cell, denom_cell):
    return "{num} / {denom}".format(num=value_ref(num_cell), denom=value_ref(denom_cell))

def safe_ratio_ref(num_cell, denom_cell):
    return "IF(OR({denom} = 0,{denom}=-1),\"\",{num} / {denom})".format(num=value_ref(num_cell), denom=value_ref(denom_cell))

def link_sheet_header(dest_sheet, ref_sheet, row, values=None):
    #Copy header
    dest_col = 1
    for col in xrange(1, ref_sheet.max_column + 1):

        ref_cell = ref_sheet.cell(row=1, column=col)

        if values != None and ref_cell.value.strip() not in values:
            continue

        dest_cell = dest_sheet.cell(row=row, column=dest_col)

        dest_cell.value = "={}".format(value_ref(ref_cell))

        dest_col += 1

def dataframe_to_sheet(wb, df, sheet_name):

    #Add to sheet
    ws = wb.create_sheet(title=sheet_name)
    for row in dataframe_to_rows(df, index=False, header=True):
        ws.append(row)

    return ws

def safe_sheet_title(raw_title):

    #Keep only file name and drop file path
    safe_title = raw_title.split('/')[-1]

    if (len(safe_title) > 31):
        safe_title = safe_title[-31:]

    #Remove all non-alphanumerical characters
    regex = re.compile(r"^\W+")
    safe_title = regex.sub("", safe_title)

    #Remove bad characters from title
    for bad_char in ['-']:
        safe_title = safe_title.replace(bad_char, '_')

    #Remove all leading zeros from title name
    safe_title = safe_title.lstrip('0')

    return safe_title

def get_task_result_files(task_name):

    task_path = os.path.join("..", "tasks", task_name)
    if (not os.path.isdir(task_path)):
        raise RuntimeError("Task is not found at {}".format(task_path))

    task_result_files = []
    task_result_files.append(os.path.join("..", "tasks", task_name, "config", "golden_results.txt"))
    task_result_files.append(os.path.join("..", "tasks", task_name, "latest", "parse_results.txt"))

    if (not os.path.isfile(task_result_files[0])):
        raise RuntimeError("Golden results of task \"{}\" doesn't exist".format(task_result_files[0]))

    if (not os.path.isfile(task_result_files[1])):
        raise RuntimeError("Latest parse results of task \"{}\" doesn't exist".format(task_result_files[1]))

    return task_result_files

if __name__ == "__main__":
    main()
