# -*- 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)
