#!/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 Utils
import logging
import fileinput
from shutil import copyfile
from Config import LoggerName, FFMPEG, HDRToolsConfigFileTemplate, HDRConvert
from Utils import GetShortContentName, ExecuteCmd, md5

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

def GenerateCfgFile(clip, outw, outh, algo, outfile, num, configpath):
    contentBaseName = GetShortContentName(clip.file_name, False)
    cfg_filename = contentBaseName + ('_Scaled_%s_%dx%d.cfg'% (algo, outw, outh))
    fmt = 1
    if (clip.fmt == '400'):
        fmt = 0
    elif (clip.fmt == '420'):
        fmt = 1
    elif (clip.fmt == '422'):
        fmt = 2
    elif (clip.fmt == '444'):
        fmt = 3

    cfgfile = os.path.join(configpath, cfg_filename)
    copyfile(HDRToolsConfigFileTemplate, cfgfile)
    fp = fileinput.input(cfgfile, inplace=1)
    for line in fp:
        if 'SourceFile=' in line:
            line = 'SourceFile="%s"\n' % clip.file_path
        if 'OutputFile=' in line:
            line = 'OutputFile="%s"\n' % outfile
        if 'SourceWidth=' in line:
            line = 'SourceWidth=%d\n' % clip.width
        if 'SourceHeight=' in line:
            line = 'SourceHeight=%d\n' % clip.height
        if 'OutputWidth=' in line:
            line = 'OutputWidth=%d\n' % outw
        if 'OutputHeight=' in line:
            line = 'OutputHeight=%d\n' % outh
        if 'SourceRate=' in line:
            line = 'SourceRate=%4.3f\n' % (float)(clip.fps_num / clip.fps_denom)
        if 'SourceChromaFormat=' in line:
            line = 'SourceChromaFormat=%d\n' % fmt
        if 'SourceBitDepthCmp0=' in line:
            line = 'SourceBitDepthCmp0=%d\n' % clip.bit_depth
        if 'SourceBitDepthCmp1=' in line:
            line = 'SourceBitDepthCmp1=%d\n' % clip.bit_depth
        if 'SourceBitDepthCmp2=' in line:
            line = 'SourceBitDepthCmp2=%d\n' % clip.bit_depth
        if 'OutputRate=' in line:
            line = 'OutputRate=%4.3f\n' % (float)(clip.fps_num / clip.fps_denom)
        if 'OutputChromaFormat=' in line:
            line = 'OutputChromaFormat=%d\n' % fmt
        if 'OutputBitDepthCmp0=' in line:
            line = 'OutputBitDepthCmp0=%d\n' % clip.bit_depth
        if 'OutputBitDepthCmp1=' in line:
            line = 'OutputBitDepthCmp1=%d\n' % clip.bit_depth
        if 'OutputBitDepthCmp2=' in line:
            line = 'OutputBitDepthCmp2=%d\n' % clip.bit_depth
        if 'NumberOfFrames=' in line:
            line = 'NumberOfFrames=%d\n' % num
        print(line, end='')
    fp.close()
    return cfgfile

def RescaleWithHDRTool(clip, outw, outh, algo, outfile, num, cfg_path,
                       LogCmdOnly = False):
    cfg_file = GenerateCfgFile(clip, outw, outh, algo, outfile, num, cfg_path)
    args = " -f %s" % cfg_file
    cmd = HDRConvert + args
    ExecuteCmd(cmd, LogCmdOnly)

def VideoRescaling(clip, num, outw, outh, outfile, algo, cfg_path,
                   LogCmdOnly = False):
    RescaleWithHDRTool(clip, outw, outh, algo, outfile, num, cfg_path, LogCmdOnly)
    # add other tools for scaling here later

####################################################################################
##################### Major Functions ################################################
def GetDownScaledOutFile(clip, dnw, dnh, path, algo):
    contentBaseName = GetShortContentName(clip.file_name, False)
    actual_algo = 'None' if clip.width == dnw and clip.height == dnh else algo
    filename = contentBaseName + ('_Scaled_%s_%dx%d.y4m' % (actual_algo, dnw,
                                                              dnh))
    dnscaledout = os.path.join(path, filename)
    return dnscaledout

def GetUpScaledOutFile(clip, outw, outh, algo, path):
    actual_algo = 'None' if clip.width == outw and clip.height == outh else algo
    filename = GetShortContentName(clip.file_name, False) + \
               ('_Scaled_%s_%dx%d.y4m' % (actual_algo, outw, outh))
    upscaledout = os.path.join(path, filename)
    return upscaledout

def GetDownScaledMD5File(clip, dnw, dnh, path, algo):
    contentBaseName = GetShortContentName(clip.file_name, False)
    actual_algo = 'None' if clip.width == dnw and clip.height == dnh else algo
    filename = contentBaseName + ('_Scaled_%s_%dx%d.md5' % (actual_algo, dnw,
                                                              dnh))
    dnscaledmd5 = os.path.join(path, filename)
    return dnscaledmd5

def DownScaling(clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
    dnScaledOut = GetDownScaledOutFile(clip, outw, outh, path, algo)

    Utils.CmdLogger.write("::Downscaling\n")
    if (clip.width == outw and clip.height == outh):
        cmd = "copy %s %s" % (clip.file_path, dnScaledOut)
        ExecuteCmd(cmd, LogCmdOnly)
    else:
        # call separate process to do the downscaling
        VideoRescaling(clip, num, outw, outh, dnScaledOut, algo, cfg_path,
                       LogCmdOnly)
    dnScaleMD5 = GetDownScaledMD5File(clip, outw, outh, path, algo)
    f = open(dnScaleMD5, 'wt')
    MD5 = md5(dnScaledOut)
    f.write(MD5)
    f.close()
    return dnScaledOut

def UpScaling(clip, num, outw, outh, path, cfg_path, algo, LogCmdOnly = False):
    upScaleOut = GetUpScaledOutFile(clip, outw, outh, algo, path)
    Utils.CmdLogger.write("::Upscaling\n")
    if (clip.width == outw and clip.height == outh):
        cmd = "copy %s %s" % (clip.file_path, upScaleOut)
        ExecuteCmd(cmd, LogCmdOnly)
    else:
        # call separate process to do the upscaling
        VideoRescaling(clip, num, outw, outh, upScaleOut, algo, cfg_path,
                       LogCmdOnly)
    return upScaleOut
