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

#-------------------------------------------------------------------------
# drawElements Quality Program utilities
# --------------------------------------
#
# Copyright 2016 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.
#
#-------------------------------------------------------------------------

import os
import argparse
import tempfile

from build.common import *
from build.build import *

class Environment:
	def __init__ (self, srcDir, tmpDir):
		self.srcDir	= srcDir
		self.tmpDir	= tmpDir

class BuildTestStep:
	def getName (self):
		return "<unknown>"

	def isAvailable (self, env):
		return True

	def run (self, env):
		raise Exception("Not implemented")

class RunScript(BuildTestStep):
	def __init__ (self, scriptPath):
		self.scriptPath = scriptPath

	def getName (self):
		return self.scriptPath

	def run (self, env):
		execute(["python", os.path.join(env.srcDir, self.scriptPath)])

def makeCflagsArgs (cflags):
	cflagsStr = " ".join(cflags)
	return ["-DCMAKE_C_FLAGS=%s" % cflagsStr, "-DCMAKE_CXX_FLAGS=%s" % cflagsStr]

def makeBuildArgs (target, cc, cpp, cflags):
	return ["-DDEQP_TARGET=%s" % target, "-DCMAKE_C_COMPILER=%s" % cc, "-DCMAKE_CXX_COMPILER=%s" % cpp] + makeCflagsArgs(cflags)

class BuildConfigGen:
	def isAvailable (self, env):
		return True

class UnixConfig(BuildConfigGen):
	def __init__ (self, target, buildType, cc, cpp, cflags):
		self.target		= target
		self.buildType	= buildType
		self.cc			= cc
		self.cpp		= cpp
		self.cflags		= cflags

	def isAvailable (self, env):
		return which(self.cc) != None and which(self.cpp) != None

	def getBuildConfig (self, env, buildDir):
		args = makeBuildArgs(self.target, self.cc, self.cpp, self.cflags)
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class VSConfig(BuildConfigGen):
	def __init__ (self, buildType):
		self.buildType = buildType

	def getBuildConfig (self, env, buildDir):
		args = ["-DCMAKE_C_FLAGS=/WX -DCMAKE_CXX_FLAGS=/WX"]
		return BuildConfig(buildDir, self.buildType, args, env.srcDir)

class Build(BuildTestStep):
	def __init__ (self, buildDir, configGen, generator):
		self.buildDir	= buildDir
		self.configGen	= configGen
		self.generator	= generator

	def getName (self):
		return self.buildDir

	def isAvailable (self, env):
		return self.configGen.isAvailable(env) and self.generator != None and self.generator.isAvailable()

	def run (self, env):
		# specialize config for env
		buildDir	= os.path.join(env.tmpDir, self.buildDir)
		curConfig	= self.configGen.getBuildConfig(env, buildDir)

		build(curConfig, self.generator)

class CheckSrcChanges(BuildTestStep):
	def getName (self):
		return "check for changes"

	def run (self, env):
		pushWorkingDir(env.srcDir)
		execute(["git", "diff", "--exit-code"])
		popWorkingDir()

def getClangVersion ():
	knownVersions = ["4.0", "3.9", "3.8", "3.7", "3.6", "3.5"]
	for version in knownVersions:
		if which("clang-" + version) != None:
			return "-" + version
	return ""

COMMON_GCC_CFLAGS	= ["-Werror"]
COMMON_CLANG_CFLAGS	= COMMON_GCC_CFLAGS + ["-Wno-error=unused-command-line-argument"]
GCC_32BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m32"]
CLANG_32BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m32"]
GCC_64BIT_CFLAGS	= COMMON_GCC_CFLAGS + ["-m64"]
CLANG_64BIT_CFLAGS	= COMMON_CLANG_CFLAGS + ["-m64"]
CLANG_VERSION		= getClangVersion()

STEPS = [
	RunScript(os.path.join("external", "fetch_sources.py")),
	Build("clang-64-debug",
		  UnixConfig("null",
					 "Debug",
					 "clang" + CLANG_VERSION,
					 "clang++" + CLANG_VERSION,
					 CLANG_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-32-debug",
		  UnixConfig("null",
					 "Debug",
					 "gcc",
					 "g++",
					 GCC_32BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("gcc-64-release",
		  UnixConfig("null",
					 "Release",
					 "gcc",
					 "g++",
					 GCC_64BIT_CFLAGS),
		  ANY_UNIX_GENERATOR),
	Build("vs-64-debug",
		  VSConfig("Debug"),
		  ANY_VS_X64_GENERATOR),
	RunScript(os.path.join("scripts", "build_android_mustpass.py")),
	RunScript(os.path.join("external", "vulkancts", "scripts", "build_mustpass.py")),
	RunScript(os.path.join("scripts", "gen_egl.py")),
	RunScript(os.path.join("scripts", "opengl", "gen_all.py")),
	RunScript(os.path.join("scripts", "src_util", "check_all.py")),
	RunScript(os.path.join("external", "vulkancts", "scripts", "gen_framework.py")),
	CheckSrcChanges(),
]

def parseArgs ():
	parser = argparse.ArgumentParser(description = "Build and test source",
									 formatter_class=argparse.ArgumentDefaultsHelpFormatter)

	parser.add_argument("-s",
						"--src-dir",
						dest="srcDir",
						default=DEQP_DIR,
						help="Source directory")
	parser.add_argument("-t",
						"--tmp-dir",
						dest="tmpDir",
						default=os.path.join(tempfile.gettempdir(), "deqp-build-test"),
						help="Temporary directory")
	return parser.parse_args()

if __name__ == "__main__":
	args	= parseArgs()
	env		= Environment(args.srcDir, args.tmpDir)

	for step in STEPS:
		if step.isAvailable(env):
			print "Run: %s" % step.getName()
			step.run(env)
		else:
			print "Skip: %s" % step.getName()

	print "All steps completed successfully"
