# -*- 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 subprocess
import sys
import argparse

def readFile (filename):
	f = open(filename, 'rb')
	d = f.read()
	f.close()
	return d

def writeFile (filename, data):
	f = open(filename, 'wb')
	f.write(data)
	f.close()

def getHead (gitDir):
	commit = subprocess.check_output(["git", "--git-dir", gitDir,
									  "rev-parse", "HEAD"])
	return commit.decode().strip()

def makeReleaseInfo (name, id, glslname, spirvtoolsname, spirvheadersname):
	return """
/* WARNING: auto-generated file, use {genFileName} to modify */

#define DEQP_RELEASE_NAME				"{releaseName}"
#define DEQP_RELEASE_ID					{releaseId}
#define DEQP_RELEASE_GLSL_NAME			"{glslReleaseName}"
#define DEQP_RELEASE_SPIRV_TOOLS_NAME	"{spirvToolsReleaseName}"
#define DEQP_RELEASE_SPIRV_HEADERS_NAME	"{spirvHeadersReleaseName}"

"""[1:].format(
		genFileName				= os.path.basename(__file__),
		releaseName				= name,
		releaseId				= id,
		glslReleaseName			= glslname,
		spirvToolsReleaseName	= spirvtoolsname,
		spirvHeadersReleaseName	= spirvheadersname)

def parseArgs ():
	parser = argparse.ArgumentParser(description="Generate release info for build")
	parser.add_argument('--name', dest='releaseName', default=None, help="Release name")
	parser.add_argument('--id', dest='releaseId', default=None, help="Release ID (must be C integer literal)")
	parser.add_argument('--git', dest='git', action='store_true', default=False, help="Development build, use git HEAD to identify")
	parser.add_argument('--git-dir', dest='gitDir', default=None, help="Use specific git dir for extracting info")
	parser.add_argument('--glsl-git-dir', dest='glslGitDir', default=None, help="Use specific git dir for extracting glsl version info")
	parser.add_argument('--glsl-spirvtools-dir', dest='spirvToolsGitDir', default=None, help="Use specific git dir for extracting spirv tools version info")
	parser.add_argument('--glsl-spirvheaders-dir', dest='spirvHeadersGitDir', default=None, help="Use specific git dir for extracting spirv headers version info")
	parser.add_argument('--out', dest='out', default=None, help="Output file")

	args = parser.parse_args()

	if (args.releaseName == None) != (args.releaseId == None):
		print "Both --name and --id must be specified"
		parser.print_help()
		sys.exit(-1)

	if (args.releaseName != None) == args.git:
		print "Either --name and --id, or --git must be specified"
		parser.print_help()
		sys.exit(-1)

	return args

if __name__ == "__main__":
	curDir						= os.path.dirname(__file__)
	defaultGitDir				= os.path.normpath(os.path.join(curDir, "..", "..", ".git"))
	defaultGlslGitDir			= os.path.normpath(os.path.join(curDir, "..", "..", "external", "glslang", "src", ".git"))
	defaultSpirvToolsGitDir		= os.path.normpath(os.path.join(curDir, "..", "..", "external", "spirv-tools", "src", ".git"))
	defaultSpirvHeadersGitDir	= os.path.normpath(os.path.join(curDir, "..", "..", "external", "spirv-headers", "src", ".git"))
	defaultDstFile				= os.path.join(curDir, "qpReleaseInfo.inl")

	args = parseArgs()

	if args.git:
		gitDir				= args.gitDir				if args.gitDir				!= None else defaultGitDir
		head				= getHead(gitDir)
		releaseName			= "git-%s" % head
		releaseId			= "0x%s" % head[0:8]
	else:
		releaseName			= args.releaseName
		releaseId			= args.releaseId

	if args.glslGitDir or os.path.exists(defaultGlslGitDir):
		glslGitDir			= args.glslGitDir			if args.glslGitDir			!= None else defaultGlslGitDir
		glslHead			= getHead(glslGitDir)
		glslName			= "git-%s" % glslHead
	elif args.git:
		glslName			= "unknown"
	else:
		glslName			= args.releaseName

	if args.spirvToolsGitDir or os.path.exists(defaultSpirvToolsGitDir):
		spirvToolsGitDir	= args.spirvToolsGitDir		if args.spirvToolsGitDir	!= None else defaultSpirvToolsGitDir
		spirvToolsHead		= getHead(spirvToolsGitDir)
		spirvToolsName		= "git-%s" % spirvToolsHead
	elif args.git:
		spirvToolsName		= "unknown"
	else:
		spirvToolsName		= args.releaseName

	if args.spirvHeadersGitDir or os.path.exists(defaultSpirvHeadersGitDir):
		spirvHeadersGitDir	= args.spirvHeadersGitDir	if args.spirvHeadersGitDir	!= None else defaultSpirvHeadersGitDir
		spirvHeadersHead	= getHead(spirvHeadersGitDir)
		spirvHeadersName	= "git-%s" % spirvHeadersHead
	elif args.git:
		spirvHeadersName	= "unknown"
	else:
		spirvHeadersName	= args.releaseName

	releaseInfo	= makeReleaseInfo(releaseName, releaseId, glslName, spirvToolsName, spirvHeadersName)
	dstFile		= args.out if args.out != None else defaultDstFile

	writeFile(dstFile, releaseInfo)
