# -*- 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, 'rt')
    d = f.read()
    f.close()
    return d

def writeFile (filename, data):
    f = open(filename, 'wt')
    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)
