## @file
# Update build revisions of the tools when performing a developer build
#
# This script will modife the C/Include/Common/BuildVersion.h file and the two
# Python scripts, Python/Common/BuildVersion.py and Python/UPT/BuildVersion.py.
# If SVN is available, the tool will obtain the current checked out version of
# the source tree for including the the --version commands.

#  Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
#
#  This program and the accompanying materials
#  are licensed and made available under the terms and conditions of the BSD License
#  which accompanies this distribution.  The full text of the license may be found at
#  http://opensource.org/licenses/bsd-license.php
#
#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
##
""" This program will update the BuildVersion.py and BuildVersion.h files used to set a tool's version value """
from __future__ import absolute_import

import os
import shlex
import subprocess
import sys

from argparse import ArgumentParser, SUPPRESS
from tempfile import NamedTemporaryFile
from types import IntType, ListType


SYS_ENV_ERR = "ERROR : %s system environment variable must be set prior to running this tool.\n"

__execname__ = "UpdateBuildVersions.py"
SVN_REVISION = "$LastChangedRevision: 3 $"
SVN_REVISION = SVN_REVISION.replace("$LastChangedRevision:", "").replace("$", "").strip()
__copyright__ = "Copyright (c) 2014, Intel Corporation. All rights reserved."
VERSION_NUMBER = "0.7.0"
__version__ = "Version %s.%s" % (VERSION_NUMBER, SVN_REVISION)


def ParseOptions():
    """
    Parse the command-line options.
    The options for this tool will be passed along to the MkBinPkg tool.
    """
    parser = ArgumentParser(
        usage=("%s [options]" % __execname__),
        description=__copyright__,
        conflict_handler='resolve')

    # Standard Tool Options
    parser.add_argument("--version", action="version",
                        version=__execname__ + " " + __version__)
    parser.add_argument("-s", "--silent", action="store_true",
                        dest="silent",
                        help="All output will be disabled, pass/fail determined by the exit code")
    parser.add_argument("-v", "--verbose", action="store_true",
                        dest="verbose",
                        help="Enable verbose output")
    # Tool specific options
    parser.add_argument("--revert", action="store_true",
                        dest="REVERT", default=False,
                        help="Revert the BuildVersion files only")
    parser.add_argument("--svn-test", action="store_true",
                        dest="TEST_SVN", default=False,
                        help="Test if the svn command is available")
    parser.add_argument("--svnFlag", action="store_true",
                        dest="HAVE_SVN", default=False,
                        help=SUPPRESS)

    return(parser.parse_args())


def ShellCommandResults(CmdLine, Opt):
    """ Execute the comand, returning the output content """
    file_list = NamedTemporaryFile(delete=False)
    filename = file_list.name
    Results = []

    returnValue = 0
    try:
        subprocess.check_call(args=shlex.split(CmdLine), stderr=subprocess.STDOUT, stdout=file_list)
    except subprocess.CalledProcessError as err_val:
        file_list.close()
        if not Opt.silent:
            sys.stderr.write("ERROR : %d : %s\n" % (err_val.returncode, err_val.__str__()))
            if os.path.exists(filename):
                sys.stderr.write("      : Partial results may be in this file: %s\n" % filename)
            sys.stderr.flush()
        returnValue = err_val.returncode

    except IOError as (errno, strerror):
        file_list.close()
        if not Opt.silent:
            sys.stderr.write("I/O ERROR : %s : %s\n" % (str(errno), strerror))
            sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)
            if os.path.exists(filename):
                sys.stderr.write("      : Partial results may be in this file: %s\n" % filename)
            sys.stderr.flush()
        returnValue = errno

    except OSError as (errno, strerror):
        file_list.close()
        if not Opt.silent:
            sys.stderr.write("OS ERROR : %s : %s\n" % (str(errno), strerror))
            sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)
            if os.path.exists(filename):
                sys.stderr.write("      : Partial results may be in this file: %s\n" % filename)
            sys.stderr.flush()
        returnValue = errno

    except KeyboardInterrupt:
        file_list.close()
        if not Opt.silent:
            sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)
            if os.path.exists(filename):
                sys.stderr.write("      : Partial results may be in this file: %s\n" % filename)
            sys.stderr.flush()
        returnValue = 1

    finally:
        if not file_list.closed:
            file_list.flush()
            os.fsync(file_list.fileno())
            file_list.close()

    if os.path.exists(filename):
        fd_ = open(filename, 'r')
        Results = fd_.readlines()
        fd_.close()
        os.unlink(filename)

    if returnValue > 0:
        return returnValue

    return Results


def UpdateBuildVersionPython(Rev, UserModified, opts):
    """ This routine will update the BuildVersion.h files in the C source tree """
    for SubDir in ["Common", "UPT"]:
        PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)
        BuildVersionPy = os.path.join(PyPath, "BuildVersion.py")
        fd_ = open(os.path.normpath(BuildVersionPy), 'r')
        contents = fd_.readlines()
        fd_.close()
        if opts.HAVE_SVN is False:
            BuildVersionOrig = os.path.join(PyPath, "orig_BuildVersion.py")
            fd_ = open (BuildVersionOrig, 'w')
            for line in contents:
                fd_.write(line)
            fd_.flush()
            fd_.close()
        new_content = []
        for line in contents:
            if line.strip().startswith("gBUILD_VERSION"):
                new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s\"" % Rev
                if UserModified:
                    new_line = "gBUILD_VERSION = \"Developer Build based on Revision: %s with Modified Sources\"" % Rev
                new_content.append(new_line)
                continue
            new_content.append(line)

        fd_ = open(os.path.normpath(BuildVersionPy), 'w')
        for line in new_content:
            fd_.write(line)
        fd_.close()


def UpdateBuildVersionH(Rev, UserModified, opts):
    """ This routine will update the BuildVersion.h files in the C source tree """
    CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")
    BuildVersionH = os.path.join(CPath, "BuildVersion.h")
    fd_ = open(os.path.normpath(BuildVersionH), 'r')
    contents = fd_.readlines()
    fd_.close()
    if opts.HAVE_SVN is False:
        BuildVersionOrig = os.path.join(CPath, "orig_BuildVersion.h")
        fd_ = open(BuildVersionOrig, 'w')
        for line in contents:
            fd_.write(line)
        fd_.flush()
        fd_.close()

    new_content = []
    for line in contents:
        if line.strip().startswith("#define"):
            new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s\"" % Rev
            if UserModified:
                new_line = "#define __BUILD_VERSION \"Developer Build based on Revision: %s with Modified Sources\"" % \
                            Rev
            new_content.append(new_line)
            continue
        new_content.append(line)

    fd_ = open(os.path.normpath(BuildVersionH), 'w')
    for line in new_content:
        fd_.write(line)
    fd_.close()


def RevertCmd(Filename, Opt):
    """ This is the shell command that does the SVN revert """
    CmdLine = "svn revert %s" % Filename.replace("\\", "/").strip()
    try:
        subprocess.check_output(args=shlex.split(CmdLine))
    except subprocess.CalledProcessError as err_val:
        if not Opt.silent:
            sys.stderr.write("Subprocess ERROR : %s\n" % err_val)
            sys.stderr.flush()

    except IOError as (errno, strerror):
        if not Opt.silent:
            sys.stderr.write("I/O ERROR : %d : %s\n" % (str(errno), strerror))
            sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)
            sys.stderr.flush()

    except OSError as (errno, strerror):
        if not Opt.silent:
            sys.stderr.write("OS ERROR : %d : %s\n" % (str(errno), strerror))
            sys.stderr.write("ERROR : this command failed : %s\n" % CmdLine)
            sys.stderr.flush()

    except KeyboardInterrupt:
        if not Opt.silent:
            sys.stderr.write("ERROR : Command terminated by user : %s\n" % CmdLine)
            sys.stderr.flush()

    if Opt.verbose:
        sys.stdout.write("Reverted this file: %s\n" % Filename)
        sys.stdout.flush()


def GetSvnRevision(opts):
    """ Get the current revision of the BaseTools/Source tree, and check if any of the files have been modified """
    Revision = "Unknown"
    Modified = False

    if opts.HAVE_SVN is False:
        sys.stderr.write("WARNING: the svn command-line tool is not available.\n")
        return (Revision, Modified)

    SrcPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source")
    # Check if there are modified files.
    Cwd = os.getcwd()
    os.chdir(SrcPath)

    StatusCmd = "svn st -v --depth infinity --non-interactive"
    contents = ShellCommandResults(StatusCmd, opts)
    os.chdir(Cwd)
    if type(contents) is ListType:
        for line in contents:
            if line.startswith("M "):
                Modified = True
                break

    # Get the repository revision of BaseTools/Source
    InfoCmd = "svn info %s" % SrcPath.replace("\\", "/").strip()
    Revision = 0
    contents = ShellCommandResults(InfoCmd, opts)
    if type(contents) is IntType:
        return 0, Modified
    for line in contents:
        line = line.strip()
        if line.startswith("Revision:"):
            Revision = line.replace("Revision:", "").strip()
            break

    return (Revision, Modified)


def CheckSvn(opts):
    """
    This routine will return True if an svn --version command succeeds, or False if it fails.
    If it failed, SVN is not available.
    """
    OriginalSilent = opts.silent
    opts.silent = True
    VerCmd = "svn --version"
    contents = ShellCommandResults(VerCmd, opts)
    opts.silent = OriginalSilent
    if type(contents) is IntType:
        if opts.verbose:
            sys.stdout.write("SVN does not appear to be available.\n")
            sys.stdout.flush()
        return False

    if opts.verbose:
        sys.stdout.write("Found %s" % contents[0])
        sys.stdout.flush()
    return True


def CopyOrig(Src, Dest, Opt):
    """ Overwrite the Dest File with the Src File content """
    try:
        fd_ = open(Src, 'r')
        contents = fd_.readlines()
        fd_.close()
        fd_ = open(Dest, 'w')
        for line in contents:
            fd_.write(line)
        fd_.flush()
        fd_.close()
    except IOError:
        if not Opt.silent:
            sys.stderr.write("Unable to restore this file: %s\n" % Dest)
            sys.stderr.flush()
        return 1

    os.remove(Src)
    if Opt.verbose:
        sys.stdout.write("Restored this file: %s\n" % Src)
        sys.stdout.flush()

    return 0


def CheckOriginals(Opts):
    """
    If SVN was not available, then the tools may have made copies of the original BuildVersion.* files using
    orig_BuildVersion.* for the name. If they exist, replace the existing BuildVersion.* file with the corresponding
    orig_BuildVersion.* file.
    Returns 0 if this succeeds, or 1 if the copy function fails. It will also return 0 if the orig_BuildVersion.* file
    does not exist.
    """
    CPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common")
    BuildVersionH = os.path.join(CPath, "BuildVersion.h")
    OrigBuildVersionH = os.path.join(CPath, "orig_BuildVersion.h")
    if not os.path.exists(OrigBuildVersionH):
        return 0
    if CopyOrig(OrigBuildVersionH, BuildVersionH, Opts):
        return 1
    for SubDir in ["Common", "UPT"]:
        PyPath = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir)
        BuildVersionPy = os.path.join(PyPath, "BuildVersion.h")
        OrigBuildVersionPy = os.path.join(PyPath, "orig_BuildVersion.h")
        if not os.path.exists(OrigBuildVersionPy):
            return 0
        if CopyOrig(OrigBuildVersionPy, BuildVersionPy, Opts):
            return 1

    return 0


def RevertBuildVersionFiles(opts):
    """
    This routine will attempt to perform an SVN --revert on each of the BuildVersion.* files
    """
    if not opts.HAVE_SVN:
        if CheckOriginals(opts):
            return 1
        return 0
    # SVN is available
    BuildVersionH = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "C", "Include", "Common", "BuildVersion.h")
    RevertCmd(BuildVersionH, opts)
    for SubDir in ["Common", "UPT"]:
        BuildVersionPy = os.path.join(os.environ['BASE_TOOLS_PATH'], "Source", "Python", SubDir, "BuildVersion.py")
        RevertCmd(BuildVersionPy, opts)

def UpdateRevisionFiles():
    """ Main routine that will update the BuildVersion.py and BuildVersion.h files."""
    options = ParseOptions()
    # Check the working environment
    if "WORKSPACE" not in os.environ.keys():
        sys.stderr.write(SYS_ENV_ERR % 'WORKSPACE')
        return 1
    if 'BASE_TOOLS_PATH' not in os.environ.keys():
        sys.stderr.write(SYS_ENV_ERR % 'BASE_TOOLS_PATH')
        return 1
    if not os.path.exists(os.environ['BASE_TOOLS_PATH']):
        sys.stderr.write("Unable to locate the %s directory." % os.environ['BASE_TOOLS_PATH'])
        return 1


    options.HAVE_SVN = CheckSvn(options)
    if options.TEST_SVN:
        return (not options.HAVE_SVN)
    # done processing the option, now use the option.HAVE_SVN as a flag. True = Have it, False = Don't have it.
    if options.REVERT:
        # Just revert the tools an exit
        RevertBuildVersionFiles(options)
    else:
        # Revert any changes in the BuildVersion.* files before setting them again.
        RevertBuildVersionFiles(options)
        Revision, Modified = GetSvnRevision(options)
        if options.verbose:
            sys.stdout.write("Revision: %s is Modified: %s\n" % (Revision, Modified))
            sys.stdout.flush()
        UpdateBuildVersionH(Revision, Modified, options)
        UpdateBuildVersionPython(Revision, Modified, options)

    return 0


if __name__ == "__main__":
    sys.exit(UpdateRevisionFiles())


