#!/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 os
import xlsxwriter
import xlrd
import logging
from CalculateQualityMetrics import CalculateQualityMetric, GatherQualityMetrics
from VideoScaler import GetDownScaledOutFile, DownScaling, UpScaling,\
     GetUpScaledOutFile
from Config import DnScaleRatio, FrameNum, QualityList, LoggerName,\
     Path_ScalingResults, ScalQty_WtCols, ScalQty_startRow, LineColors, \
     ScalSumQty_WtCols
from Utils import Cleanfolder, GetShortContentName, CreateChart_Scatter, \
     AddSeriesToChart_Scatter, UpdateChart, InsertChartsToSheet, \
     CalcRowsClassAndContentDict, Clip, CreateChart_Bar, AddSeriesToChart_Bar

subloggername = "ScalingTest"
loggername = LoggerName + '.' + '%s' % subloggername
logger = logging.getLogger(loggername)

StatsMetrics = ['Max', 'Std+', 'Average', 'Std-', 'Min']

def GetScalingResultExcelFile(method, rationum, scalAlgoNum):
    filename = "ScalingResults_RatioNum_%d_%s_AlgoNum_%d.xlsx"\
               % (rationum, method, scalAlgoNum)
    file = os.path.join(Path_ScalingResults, filename)
    return file

def GetScalingResultExcelFile_PerContent(content, method):
    filename = GetShortContentName(content, False)
    filename = "ScalingResults_%s_%s.xlsx" % (method, filename)
    file = os.path.join(Path_ScalingResults, filename)
    return file

def Run_Scaling_Test(clip, dnScalAlgo, upScalAlgo, path_dnscl, path_upscl,
                     path_log, path_cfg, savememory, keepupscaledyuv, ScaleMethod,
                     LogCmdOnly=False):
    logger.info("start running scaling tests with content %s"
                % os.path.basename(clip.file_name))
    DnScaledRes = [(int(clip.width / ratio), int(clip.height / ratio))
                   for ratio in DnScaleRatio]
    for i in range(len(DnScaledRes)):
        if savememory:
            Cleanfolder(path_cfg)
            if not keepupscaledyuv:
                Cleanfolder(path_upscl)

        DnScaledW = DnScaledRes[i][0]
        DnScaledH = DnScaledRes[i][1]
        logger.info("start downscaling content to %dx%d" % (DnScaledW, DnScaledH))
        # downscaling
        dnscalyuv = GetDownScaledOutFile(clip, DnScaledW, DnScaledH,
                                         path_dnscl, ScaleMethod, dnScalAlgo)
        if not os.path.isfile(dnscalyuv):
            dnscalyuv = DownScaling(ScaleMethod, clip, FrameNum['AS'], DnScaledW, DnScaledH,
                                    path_dnscl, path_cfg, dnScalAlgo, LogCmdOnly)
        dnscaled_clip = Clip(GetShortContentName(dnscalyuv, False)+'.y4m',
                             dnscalyuv, "", DnScaledW, DnScaledH,
                             clip.fmt, clip.fps_num, clip.fps_denom,
                             clip.bit_depth)
        upscaleyuv = UpScaling(ScaleMethod, dnscaled_clip, FrameNum['AS'], clip.width, clip.height,
                               path_upscl, path_cfg, upScalAlgo, LogCmdOnly)
        CalculateQualityMetric(clip.file_path, FrameNum['AS'], upscaleyuv, clip.fmt,
                               clip.width, clip.height, clip.bit_depth,
                               path_log, LogCmdOnly)
    if savememory:
        Cleanfolder(path_dnscl)

    logger.info("finish running scaling test.")

def GeneratePerClipExcelFile(ScaleMethod, dnScalAlgos, upScalAlgos, clip, path_log):
    logger.info("start generate excel file for content :%s" % clip.file_name)
    excFile = GetScalingResultExcelFile_PerContent(clip.file_name, ScaleMethod)
    wb = xlsxwriter.Workbook(excFile)
    shtname = GetShortContentName(clip.file_name)
    sht = wb.add_worksheet(shtname)

    sht.write(1, 0, 'Content Name')
    sht.write(2, 0, clip.file_name)
    sht.write(1, 1, 'Scaling Ratio')
    sht.write_column(2, 1, DnScaleRatio)
    pre_title = ['Width', 'Height', 'DnScaledWidth', 'DnScaledHeight']
    sht.write_row(1, 2, pre_title)
    for dn_algo, up_algo, col in zip(dnScalAlgos, upScalAlgos, ScalQty_WtCols):
        algos = dn_algo + '--' + up_algo
        sht.write(0, col, algos)
        sht.write_row(1, col, QualityList)

    rows = [ScalQty_startRow + i for i in range(len(DnScaleRatio))]
    continfos = []
    for ratio, row in zip(DnScaleRatio, rows):
        dw = int(clip.width / ratio)
        dh = int(clip.height / ratio)
        info = [clip.width, clip.height, dw, dh]
        sht.write_row(row, 2, info)
        continfos.append(info)

    charts = []; y_mins = {}; y_maxs = {}
    for qty, x in zip(QualityList, range(len(QualityList))):
        chart_title = 'Scaling Quality - %s' % qty
        xaxis_name = 'scaling ratio'
        chart = CreateChart_Scatter(wb, chart_title, xaxis_name, qty)
        charts.append(chart)
        y_mins[x] = []; y_maxs[x] = []

    for dn_algo, up_algo, col, i in zip(dnScalAlgos, upScalAlgos, ScalQty_WtCols,
                                        range(len(dnScalAlgos))):
        qualities = []
        seriname = dn_algo + '--' + up_algo
        for ratio, row, idx in zip(DnScaleRatio, rows, range(len(DnScaleRatio))):
            w = continfos[idx][0]
            h = continfos[idx][1]
            dw = continfos[idx][2]
            dh = continfos[idx][3]
            dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, ScaleMethod, dn_algo)
            ds_clip = Clip(GetShortContentName(dnScalOut, False) + '.y4m',
                 dnScalOut, "", dw, dh, clip.fmt, clip.fps_num, clip.fps_denom,
                 clip.bit_depth)
            upScalOut = GetUpScaledOutFile(ds_clip, clip.width, clip.height,
                                           ScaleMethod, up_algo, path_log)
            qtys, perframe_vmaf_log = GatherQualityMetrics(upScalOut, path_log)
            sht.write_row(row, col, qtys)
            qualities.append(qtys)
        for x in range(len(QualityList)):
            AddSeriesToChart_Scatter(shtname, rows, col + x, 1, charts[x],
                                     seriname, LineColors[i])

        # get min and max of y-axis for a certain dn up scaling algo
        for qty, x in zip(QualityList, range(len(QualityList))):
            qs = [row[x] for row in qualities]
            y_mins[x].append(min(qs))
            y_maxs[x].append(max(qs))

    for qty, x in zip(QualityList, range(len(QualityList))):
        ymin = min(y_mins[x])
        ymax = max(y_maxs[x])
        margin = 0.1  # add 10% on min and max value for y_axis range
        num_precsn = 5 if 'MS-SSIM' in qty else 3
        UpdateChart(charts[x], ymin, ymax, margin, qty, num_precsn)

    startrow = rows[-1] + 2; startcol = 1
    InsertChartsToSheet(sht, startrow, startcol, charts)

    wb.close()
    logger.info("finish export scaling quality results to excel file.")

def GenerateSummarySheet(wb, ScaleMethod, dnScalAlgos, upScalAlgos, ratio, path_log):
    logger.info("start generate summary sheet for ratio %2.2f" % ratio)

    shts = []
    shtname = "Ratio=%1.2f" % ratio
    sht = wb.add_worksheet(shtname)
    shts.append(sht)
    sht.write(1, 0, 'Content Class')
    sht.write(1, 1, 'Content NO.')
    sht.write(1, 2, 'Content Name')
    pre_title = ['Width', 'Height', 'DnScaledWidth', 'DnScaledHeight']
    sht.write_row(1, 3, pre_title)

    for dn_algo, up_algo, col in zip(dnScalAlgos, upScalAlgos, ScalSumQty_WtCols):
        algos = dn_algo + '--' + up_algo
        sht.write(0, col, algos)
        sht.write_row(1, col, QualityList)

    content_infos = {}; totalnum_contents = 0
    for (clss, clip_list), row_clss in zip(ClipDict.items(), Rows_Class):
        sht.write(row_clss, 0, clss)
        totalnum_contents = totalnum_contents + len(clip_list)
        for clip, row_cont in zip(clip_list, range(len(clip_list))):
            dw = int(clip.width / ratio)
            dh = int(clip.height / ratio)
            shortcntname = GetShortContentName(clip.file_name, False)
            sht.write(row_clss + row_cont, 2, shortcntname)
            infos = [clip.width, clip.height, dw, dh]
            sht.write_row(row_clss + row_cont, 3, infos)
            content_infos[shortcntname] = infos

    charts = []; y_mins = {}; y_maxs = {}
    for qty, x in zip(QualityList, range(len(QualityList))):
        chart_title = '%s of %s' % (qty, shtname)
        chart = CreateChart_Bar(wb, chart_title, 'Contents', qty)
        charts.append(chart)
        y_mins[x] = []; y_maxs[x] = []

    rows_all = [ScalQty_startRow + i for i in range(totalnum_contents)]
    sht.write_column(ScalQty_startRow, 1, range(totalnum_contents))
    for dn_algo, up_algo, col, i in zip(dnScalAlgos, upScalAlgos,
                                        ScalSumQty_WtCols,
                                        range(len(dnScalAlgos))):
        qualities = []
        seriname = dn_algo + '--' + up_algo
        for (clss, clip_list), row_clss in zip(ClipDict.items(), Rows_Class):
            for clip, row_cont in zip(clip_list, range(len(clip_list))):
                key = GetShortContentName(clip.file_name, False)
                w = content_infos[key][0]
                h = content_infos[key][1]
                dw = content_infos[key][2]
                dh = content_infos[key][3]
                dnScalOut = GetDownScaledOutFile(clip, dw, dh, path_log, ScaleMethod, dn_algo)
                ds_clip = Clip(GetShortContentName(dnScalOut, False) + '.y4m',
                               dnScalOut, clss, dw, dh, clip.fmt, clip.fps_num,
                               clip.fps_denom, clip.bit_depth)
                upScalOut = GetUpScaledOutFile(ds_clip, w, h, ScaleMethod, up_algo, path_log)
                qtys, perframe_vmaf_log = GatherQualityMetrics(upScalOut, path_log)
                sht.write_row(row_clss + row_cont, col, qtys)
                qualities.append(qtys)

        for x in range(len(QualityList)):
            AddSeriesToChart_Bar(shtname, rows_all, col + x, 1, charts[x], seriname)

        # get min and max of y-axis for a certain dn up scaling algo
        for qty, x in zip(QualityList, range(len(QualityList))):
            qs = [row[x] for row in qualities]
            y_mins[x].append(min(qs))
            y_maxs[x].append(max(qs))

    for qty, x in zip(QualityList, range(len(QualityList))):
        ymin = min(y_mins[x])
        ymax = max(y_maxs[x])
        margin = 0.1  # add 10% on min and max value for y_axis range
        num_precsn = 5 if 'MS-SSIM' in qty else 3
        UpdateChart(charts[x], ymin, ymax, margin, qty, num_precsn)

    startrow = rows_all[-1] + 2; startcol = 1
    InsertChartsToSheet(sht, startrow, startcol, charts)
    logger.info("finish average sheet for ratio:%2.2f." % ratio)

    return sht

def GenerateAverageSheet(wb, sumsht, dnScalAlgos, upScalAlgos, ratio):
    logger.info("start generate average sheet for ratio %2.2f" % ratio)

    rdsht = sumsht
    rdshtname = rdsht.get_name()
    shtname = "AverageForRatio=%1.2f" % ratio
    sht = wb.add_worksheet(shtname)
    sht.write(1, 0, 'QualityMetrics')
    sht.write(1, 1, 'Content Class')
    sht.write(1, 2, 'Content Number')

    interval = 1
    step = len(StatsMetrics) + interval
    startcol = 3
    cols_avg = [startcol + step * i for i in range(len(dnScalAlgos))]
    for col, dn_algo, up_algo in zip(cols_avg, dnScalAlgos, upScalAlgos):
        algos = dn_algo + '--' + up_algo
        sht.write(0, col, algos)
        sht.write_row(1, col, StatsMetrics)

    step = len(ClipDict) + 1  # 1 extra row for total of each class
    startrow = 2
    rows_qtymtr = [startrow + step * i for i in range(len(QualityList))]
    for qty, row_qm, y in zip(QualityList, rows_qtymtr, range(len(QualityList))):
        sht.write(row_qm, 0, qty)

        #charts = []
        #titlename = 'Quality Statistics %s' % qty
        #chart = CreateChart_Line(wb, titlename, qty)
        #charts.append(chart)

        totalnum_contents = 0
        for (cls, clip_list), idx, rdrow_cls in zip(ClipDict.items(),
                                                   range(len(ClipDict)),
                                                   Rows_Class):
            sht.write(row_qm + idx, 1, cls)
            num_content = len(clip_list)
            totalnum_contents = totalnum_contents + num_content
            sht.write(row_qm + idx, 2, num_content)
            for rdcol, wtcol in zip(ScalSumQty_WtCols, cols_avg):
                startcell = xlrd.cellname(rdrow_cls, rdcol + y)
                endcell = xlrd.cellname(rdrow_cls + num_content - 1, rdcol + y)
                formula = '=MAX(\'%s\'!%s:%s)' % (rdshtname, startcell, endcell)
                sht.write(row_qm + idx, wtcol, formula)

                formula = '=SUM(\'%s\'!%s:%s)/%d' % (rdshtname, startcell,
                                                     endcell, num_content)
                sht.write(row_qm + idx, wtcol + 2, formula)

                formula = '=MIN(\'%s\'!%s:%s)' % (rdshtname, startcell, endcell)
                sht.write(row_qm + idx, wtcol + 4, formula)

                avgcell = xlrd.cellname(row_qm + idx, wtcol + 2)
                formula = '= %s + _xlfn.STDEV.P(\'%s\'!%s:%s)'\
                          % (avgcell, rdshtname, startcell, endcell)
                sht.write(row_qm + idx, wtcol + 1, formula)

                formula = '= %s - _xlfn.STDEV.P(\'%s\'!%s:%s)'\
                          % (avgcell, rdshtname, startcell, endcell)
                sht.write(row_qm + idx, wtcol + 3, formula)

        #write total contents statistics
        wtrow = row_qm + len(ClipDict)
        sht.write(wtrow, 1, 'Total')
        sht.write(wtrow, 2, totalnum_contents)
        for rdcol, wtcol in zip(ScalSumQty_WtCols, cols_avg):
            startcell = xlrd.cellname(ScalQty_startRow, rdcol + y)
            endcell = xlrd.cellname(ScalQty_startRow + totalnum_contents - 1,
                                    rdcol + y)
            formula = '=MAX(\'%s\'!%s:%s)' % (rdshtname, startcell, endcell)
            sht.write(wtrow, wtcol, formula)

            formula = '=SUM(\'%s\'!%s:%s)/%d'\
                      % (rdshtname, startcell, endcell, totalnum_contents)
            sht.write(wtrow, wtcol + 2, formula)

            formula = '=MIN(\'%s\'!%s:%s)' % (rdshtname, startcell, endcell)
            sht.write(wtrow, wtcol + 4, formula)

            avgcell = xlrd.cellname(wtrow, wtcol + 2)
            formula = '= %s + _xlfn.STDEV.P(\'%s\'!%s:%s)'\
                      % (avgcell, rdshtname, startcell, endcell)
            sht.write(wtrow, wtcol + 1, formula)

            formula = '= %s - _xlfn.STDEV.P(\'%s\'!%s:%s)'\
                      % (avgcell, rdshtname, startcell, endcell)
            sht.write(wtrow, wtcol + 3, formula)

    logger.info("finish average sheet for ratio:%2.2f." % ratio)

def SaveScalingResultsToExcel(ScaleMethod, dnScalAlgos, upScalAlgos, clip_list, path_log):
    logger.info("start saving scaling quality results to excel files.......")
    if not os.path.exists(Path_ScalingResults):
        os.makedirs(Path_ScalingResults)

    logger.info("start generating per content scaling quality excel file.......")
    for clip in clip_list:
        GeneratePerClipExcelFile(ScaleMethod, dnScalAlgos, upScalAlgos, clip, path_log)

    scaleRatios = DnScaleRatio
    if (1.0 in scaleRatios):
        scaleRatios.remove(1.0)
    logger.info("start generating scaling quality summary excel file.......")
    sumexcFile = GetScalingResultExcelFile(ScaleMethod, len(scaleRatios), len(dnScalAlgos))
    wb = xlsxwriter.Workbook(sumexcFile)
    # to generate rows number of starting of each class: Rows_Class
    global ClipDict, Rows_Class
    ClipDict, Rows_Class = CalcRowsClassAndContentDict(ScalQty_startRow,  clip_list)
    sumShts = []
    for ratio in scaleRatios:
        sht = GenerateSummarySheet(wb, ScaleMethod, dnScalAlgos, upScalAlgos, ratio, path_log)
        sumShts.append(sht)
    for ratio, sumsht in zip(scaleRatios, sumShts):
        GenerateAverageSheet(wb, sumsht, dnScalAlgos, upScalAlgos, ratio)

    wb.close()
    logger.info("finish saving scaling quality results to excel files.......")
