#!/usr/bin/env python
## Copyright (c) 2019, Alliance for Open Media. All rights reserved
##
## This source code is subject to the terms of the BSD 2 Clause License and
## the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
## was not distributed with this source code in the LICENSE file, you can
## obtain it at www.aomedia.org/license/software. If the Alliance for Open
## Media Patent License 1.0 was not distributed with this source code in the
## PATENTS file, you can obtain it at www.aomedia.org/license/patent.
##
__author__ = "maggie.sun@intel.com, ryan.lei@intel.com"

import sys
import xlsxwriter
import xlrd
import argparse
from Config import VbaBinFile, QualityList, CalcBDRateInExcel, \
     EnablePreInterpolation
from CalcBDRate import BD_RATE


class ConvexHullData:
    ContentName = ""
    ContentClass = ""
    NumRDPoints = 0
    RDPoints = {}

    def __init__(self, Name="", Class="", num=0):
        self.ContentName = Name
        self.ContentClass = Class
        self.NumRDPoints = num
        self.RDPoints = {}


def ParseArguments(raw_args):
    parser = argparse.ArgumentParser(prog='ConvexHullBDRate.py',
                                     usage='%(prog)s [options]', description='')
    parser.add_argument('-i1', '--input1', dest='Input1', type=str,
                        required=True, metavar='',
                        help="convex hull summary excel file for base mode")
    parser.add_argument('-i2', '--input2', dest='Input2', type=str,
                        required=True, metavar='',
                        help="convex hull summary excel file for target mode")
    parser.add_argument('-o', '--output', dest='Output', type=str,
                        required=True, metavar='',
                        help="output excel file with BDRATE for base and target"
                             " modes")
    if len(raw_args) == 1:
        parser.print_help()
        sys.exit(1)
    args = parser.parse_args(raw_args[1:])

    global InputBase, InputTarget, Output
    InputBase = args.Input1
    InputTarget = args.Input2
    Output = args.Output


def read_cell_as_str(sht, row, col):
    cell_val = sht.cell(row, col).value
    if cell_val == '':
        return ''
    else:
        return str(cell_val)


def read_cell_as_float(sht, row, col):
    cell_val = sht.cell(row, col).value
    if cell_val == '':
        return ''
    else:
        return float(cell_val)


def read_cell_as_int(sht, row, col):
    cell_val = sht.cell(row, col).value
    if cell_val == '':
        return ''
    else:
        return int(cell_val)


def ParseConvexHullRD(xls, EnablePreInterpolation = False):
    wb = xlrd.open_workbook(xls)
    shts = wb.sheet_names()   #list of sheet names
    data = {}   #dict of data, key is the sheet name

    cvx_cols = 4
    if EnablePreInterpolation:
        cvx_cols = 6

    cols = [3 + i * cvx_cols for i in range(len(QualityList))]
    for sht_name in shts:
        sht = wb.sheet_by_name(sht_name)
        #skip the title row
        rows = sht.nrows
        start_row = 1
        while start_row < rows:
            row = start_row
            cls = read_cell_as_str(sht, row, 0)
            name = read_cell_as_str(sht, row, 1)
            num = read_cell_as_int(sht, row, 2)
            if cls == '' or name == '' or num == '':
                print("Error: read empty cells")
                exit()

            point = ConvexHullData(name, cls, num)
            rd_data = {}
            for row in range(num):
                for qty, col in zip(QualityList, cols):
                    res = read_cell_as_str(sht, start_row+row, col)         #Resolution
                    qp  = read_cell_as_int(sht, start_row+row, col + 1)     #QP
                    br  = read_cell_as_float(sht, start_row+row, col + 2)   #Bitrate
                    q   = read_cell_as_float(sht, start_row+row, col + 3)   #Quality
                    if EnablePreInterpolation:
                        int_br = read_cell_as_float(sht, start_row+row, col + 4)   #Int_Bitrate
                        int_q = read_cell_as_float(sht, start_row+row, col + 5)  # Int_Quality
                        if int_br != '' and int_q != '':
                            if qty in rd_data:
                                rd_data[qty].append((br, q, int_br, int_q))
                            else:
                                rd_data.update({qty: [(br, q, int_br, int_q)]})
                    else:
                        if br != '' and q != '':
                            if qty in rd_data:
                                rd_data[qty].append((br, q))
                            else:
                                rd_data.update({qty: [(br, q)]})

            start_row += num
            point.RDPoints = rd_data
            if sht_name in data:
                data[sht_name].append(point)
            else:
                data.update({sht_name: [point]})

    return shts, data


def WriteOutputHeaderRow(sht, EnablePreInterpolation = False):
    sht.write(0, 0, 'Content Class')
    sht.write(0, 1, 'Content Name')
    sht.write(0, 2, 'Num RD Points')
    col = 3
    for qty in QualityList:
        sht.write(0, col, 'Bitrate(kbps)')
        sht.write(0, col + 1, qty)
        if EnablePreInterpolation:
            sht.write(0, col + 2, 'Int_Bitrate(kbps)')
            sht.write(0, col + 3, 'Int_' + qty)
            col += 4
        else:
            col += 2

    col += 1
    for qty in QualityList:
        sht.write(0, col, 'Bitrate(kbps)')
        sht.write(0, col + 1, qty)
        if EnablePreInterpolation:
            sht.write(0, col + 2, 'Int_Bitrate(kbps)')
            sht.write(0, col + 3, 'Int_' + qty)
            col += 4
        else:
            col += 2
    col += 1
    for (idx, qty) in zip(range(len(QualityList)), QualityList):
        sht.write(0, col + idx, "BDRATE-%s" % qty)


def WriteRDData(sht, rd_data, start_row, start_col, format,
                EnablePreInterpolation = False):
    col = start_col
    max_rows = 0
    for qty in QualityList:
        row = start_row
        for (line, point) in zip(range(len(rd_data.RDPoints[qty])),
                                 rd_data.RDPoints[qty]):
            if point[0] != '':
                sht.write_number(row + line, col, point[0], format)        #Bitrate
            if point[1] != '':
                sht.write_number(row + line, col + 1, point[1], format)    #Quality
            if EnablePreInterpolation:
                if point[2] != '':
                    sht.write_number(row + line, col + 2, point[2], format)  # Int_Bitrate
                if point[3] != '':
                    sht.write_number(row + line, col + 3, point[3], format)  # Int_Quality
        if EnablePreInterpolation:
            col += 4
        else:
            col += 2
        max_rows = max(max_rows, len(rd_data.RDPoints[qty]))
    return max_rows


def WriteRDRecord(sht, base_data, target_data, start_row, bdrate_fmt, float_fmt,
                  EnablePreInterpolation = False):
    sht.write(start_row, 0, base_data.ContentClass)
    sht.write(start_row, 1, base_data.ContentName)

    #write base data
    base_start_col = 3
    cvx_cols = 2
    if EnablePreInterpolation:
        cvx_cols = 4

    base_max_rows = WriteRDData(sht, base_data, start_row, base_start_col,
                                float_fmt, EnablePreInterpolation)

    #write target data
    target_start_col = base_start_col + cvx_cols * len(QualityList) + 1
    target_max_rows = WriteRDData(sht, target_data, start_row, target_start_col,
                                  float_fmt, EnablePreInterpolation)

    #write bdrate formula
    bdrate_start_col = target_start_col + cvx_cols * len(QualityList) + 1
    total_rows = max(base_max_rows, target_max_rows)
    sht.write(start_row, 2, total_rows)
    for (qty, col) in zip(QualityList, range(len(QualityList))):
        if CalcBDRateInExcel:
            refbr_b = xlrd.cellnameabs(start_row,
                                       base_start_col + col * cvx_cols)
            refbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                       base_start_col + col * cvx_cols)
            refq_b = xlrd.cellnameabs(start_row,
                                      base_start_col + col * cvx_cols + 1)
            refq_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                      base_start_col + col * cvx_cols + 1)

            testbr_b = xlrd.cellnameabs(start_row,
                                        target_start_col + col * cvx_cols)
            testbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                        target_start_col + col * cvx_cols)
            testq_b = xlrd.cellnameabs(start_row,
                                       target_start_col + col * cvx_cols + 1)
            testq_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                       target_start_col + col * cvx_cols + 1)

            # formula = '=-bdrate(%s:%s,%s:%s,%s:%s,%s:%s)' % (
            # refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b, testq_e)
            formula = '=bdRateExtend(%s:%s,%s:%s,%s:%s,%s:%s)'\
                % (refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b, testq_e)
            sht.write_formula(start_row, bdrate_start_col + col, formula, bdrate_fmt)

            if EnablePreInterpolation:
                refbr_b = xlrd.cellnameabs(start_row,
                                           base_start_col + col * cvx_cols + 2)
                refbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                           base_start_col + col * cvx_cols + 2)
                refq_b = xlrd.cellnameabs(start_row,
                                          base_start_col + col * cvx_cols + 3)
                refq_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                          base_start_col + col * cvx_cols + 3)

                testbr_b = xlrd.cellnameabs(start_row,
                                            target_start_col + col * cvx_cols + 2)
                testbr_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                            target_start_col + col * cvx_cols + 2)
                testq_b = xlrd.cellnameabs(start_row,
                                           target_start_col + col * cvx_cols + 3)
                testq_e = xlrd.cellnameabs(start_row + total_rows - 1,
                                           target_start_col + col * cvx_cols + 3)
                formula = '=bdRateExtend(%s:%s,%s:%s,%s:%s,%s:%s)' \
                    % (refbr_b, refbr_e, refq_b, refq_e, testbr_b, testbr_e, testq_b,
                       testq_e)

                sht.write_formula(start_row + 1, bdrate_start_col + col, formula, bdrate_fmt)
        else:
            refbrs   = [base_data.RDPoints[qty][i][0] for i in range(len(base_data.RDPoints[qty]))]
            refqtys  = [base_data.RDPoints[qty][i][1] for i in range(len(base_data.RDPoints[qty]))]
            testbrs  = [target_data.RDPoints[qty][i][0] for i in range(len(target_data.RDPoints[qty]))]
            testqtys = [target_data.RDPoints[qty][i][1] for i in range(len(target_data.RDPoints[qty]))]
            bdrate = BD_RATE(qty, refbrs, refqtys, testbrs, testqtys)
            if (bdrate != 'Non-monotonic Error'):
                bdrate /=  100.0
                sht.write_number(start_row, bdrate_start_col + col, bdrate, bdrate_fmt)
            else:
                sht.write(start_row, bdrate_start_col + col, bdrate)
            if EnablePreInterpolation:
                refbrs = [base_data.RDPoints[qty][i][2] for i in range(len(base_data.RDPoints[qty]))]
                refqtys = [base_data.RDPoints[qty][i][3] for i in range(len(base_data.RDPoints[qty]))]
                testbrs = [target_data.RDPoints[qty][i][2] for i in range(len(target_data.RDPoints[qty]))]
                testqtys = [target_data.RDPoints[qty][i][3] for i in range(len(target_data.RDPoints[qty]))]
                bdrate = BD_RATE(qty, refbrs, refqtys, testbrs, testqtys)
                if (bdrate != 'Non-monotonic Error'):
                    bdrate /= 100.0
                    sht.write_number(start_row + 1, bdrate_start_col + col, bdrate, bdrate_fmt)
                else:
                    sht.write(start_row + 1, bdrate_start_col + col, bdrate)
    return total_rows


def FindContent(name, rd_data):
    for data in rd_data:
        if name == data.ContentName:
            return data
    return ''

######################################
# main
######################################
if __name__ == "__main__":
    #sys.argv = ["","-i1","ConvexHullData_ScaleAlgosNum_6_aom_av1_1.xlsx",
    #"-i2","ConvexHullData_ScaleAlgosNum_6_aom_av1_6.xlsx",
    #"-o","ConvexHullBDRate.xlsm"]
    ParseArguments(sys.argv)

    base_shts, base_rd_data = ParseConvexHullRD(InputBase, EnablePreInterpolation)
    target_shts, target_rd_data = ParseConvexHullRD(InputTarget, EnablePreInterpolation)

    output_wb = xlsxwriter.Workbook(Output)
    # vba file needed when to calculate bdrate
    output_wb.add_vba_project(VbaBinFile)
    bdrate_fmt = output_wb.add_format()
    bdrate_fmt.set_num_format('0.00%')
    float_fmt = output_wb.add_format()
    float_fmt.set_num_format('0.00')

    for sht_name in base_shts:
        if sht_name in target_shts:
            sht = output_wb.add_worksheet(sht_name)
            WriteOutputHeaderRow(sht, False)
            start_row = 1
            for base_data in base_rd_data[sht_name]:
                ContentName = base_data.ContentName
                target_data = FindContent(ContentName, target_rd_data[sht_name])
                if target_data != '':
                    total_rows = WriteRDRecord(sht, base_data, target_data,
                                               start_row, bdrate_fmt, float_fmt,
                                               EnablePreInterpolation)
                    start_row += total_rows

    output_wb.close()
