# -*- coding: utf-8 -*-

#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#-------------------------------------------------------------------------

from ctsbuild.common import *
from ctsbuild.config import *
from ctsbuild.build import *

import os
import sys
import string
import argparse
import tempfile
import shutil

class Module:
    def __init__ (self, name, dirName, binName):
        self.name = name
        self.dirName = dirName
        self.binName = binName

MODULES = [
    Module("dE-IT", "internal", "de-internal-tests"),
    Module("dEQP-EGL", "egl", "deqp-egl"),
    Module("dEQP-GLES2", "gles2", "deqp-gles2"),
    Module("dEQP-GLES3", "gles3", "deqp-gles3"),
    Module("dEQP-GLES31", "gles31", "deqp-gles31"),
    Module("dEQP-VK", "../external/vulkancts/modules/vulkan", "deqp-vk"),
    Module("dEQP-VKSC", "../external/vulkancts/modules/vulkan", "deqp-vksc"),
]

DEFAULT_BUILD_DIR = os.path.join(tempfile.gettempdir(), "deqp-caselists", "{targetName}-{buildType}")
DEFAULT_TARGET = "null"

def getModuleByName (name):
    for module in MODULES:
        if module.name == name:
            return module
    else:
        raise Exception("Unknown module %s" % name)

def getBuildConfig (buildPathPtrn, targetName, buildType):
    buildPath = buildPathPtrn.format(
        targetName = targetName,
        buildType = buildType)

    return BuildConfig(buildPath, buildType, ["-DDEQP_TARGET=%s" % targetName])

def getModulesPath (buildCfg):
    return os.path.join(buildCfg.getBuildDir(), "modules")

def getBuiltModules (buildCfg):
    modules = []
    modulesDir = getModulesPath(buildCfg)

    for module in MODULES:
        fullPath = os.path.join(modulesDir, module.dirName)
        if os.path.exists(fullPath) and os.path.isdir(fullPath):
            modules.append(module)

    return modules

def getCaseListFileName (module, caseListType):
    return "%s-cases.%s" % (module.name, caseListType)

def getCaseListPath (buildCfg, module, caseListType):
    return os.path.join(getModulesPath(buildCfg), module.dirName, getCaseListFileName(module, caseListType))

def genCaseList (buildCfg, generator, module, caseListType):
    workDir = os.path.join(getModulesPath(buildCfg), module.dirName)

    pushWorkingDir(workDir)

    try:
        binPath = generator.getBinaryPath(buildCfg.getBuildType(), os.path.join(".", module.binName))
        execute([binPath, "--deqp-runmode=%s-caselist" % caseListType])
    finally:
        popWorkingDir()

def genAndCopyCaseList (buildCfg, generator, module, dstDir, caseListType):
    caseListFile = getCaseListFileName(module, caseListType)
    srcPath = getCaseListPath(buildCfg, module, caseListType)
    dstPath = os.path.join(dstDir, caseListFile)

    if os.path.exists(srcPath):
        os.remove(srcPath)

    genCaseList(buildCfg, generator, module, caseListType)

    if not os.path.exists(srcPath):
        raise Exception("%s not generated" % srcPath)

    shutil.copyfile(srcPath, dstPath)

def parseArgs ():
    parser = argparse.ArgumentParser(description = "Build test case lists",
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("-b",
                        "--build-dir",
                        dest="buildDir",
                        default=DEFAULT_BUILD_DIR,
                        help="Temporary build directory")
    parser.add_argument("-t",
                        "--build-type",
                        dest="buildType",
                        default="Debug",
                        help="Build type")
    parser.add_argument("-c",
                        "--deqp-target",
                        dest="targetName",
                        default=DEFAULT_TARGET,
                        help="dEQP build target")
    parser.add_argument("--case-list-type",
                        dest="caseListType",
                        default="xml",
                        help="Case list type (xml, txt)")
    parser.add_argument("-m",
                        "--modules",
                        dest="modules",
                        help="Comma-separated list of modules to update")
    parser.add_argument("dst",
                        help="Destination directory for test case lists")
    return parser.parse_args()

if __name__ == "__main__":
    args = parseArgs()

    generator = ANY_GENERATOR
    buildCfg = getBuildConfig(args.buildDir, args.targetName, args.buildType)
    modules = None

    if args.modules:
        modules = []
        for m in args.modules.split(","):
            modules.append(getModuleByName(m))

    if modules:
        build(buildCfg, generator, [m.binName for m in modules])
    else:
        build(buildCfg, generator)
        modules = getBuiltModules(buildCfg)

    for module in modules:
        print("Generating test case list for %s" % module.name)
        genAndCopyCaseList(buildCfg, generator, module, args.dst, args.caseListType)
