#!/usr/bin/env python

"""Gets the current revision and writes it to VCSRevision.h."""

from __future__ import print_function

import argparse
import os
import subprocess
import sys


THIS_DIR = os.path.abspath(os.path.dirname(__file__))
LLVM_DIR = os.path.dirname(os.path.dirname(os.path.dirname(THIS_DIR)))


def which(program):
    # distutils.spawn.which() doesn't find .bat files,
    # https://bugs.python.org/issue2200
    for path in os.environ["PATH"].split(os.pathsep):
        candidate = os.path.join(path, program)
        if os.path.isfile(candidate) and os.access(candidate, os.X_OK):
            return candidate
    return None


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-d', '--depfile',
                        help='if set, writes a depfile that causes this script '
                             'to re-run each time the current revision changes')
    parser.add_argument('--write-git-rev', action='store_true',
                        help='if set, writes git revision, else writes #undef')
    parser.add_argument('--name', action='append',
                        help='if set, writes a depfile that causes this script '
                             'to re-run each time the current revision changes')
    parser.add_argument('vcs_header', help='path to the output file to write')
    args = parser.parse_args()

    vcsrevision_contents = ''
    if args.write_git_rev:
        git, use_shell = which('git'), False
        if not git: git = which('git.exe')
        if not git: git, use_shell = which('git.bat'), True
        git_dir = subprocess.check_output(
                [git, 'rev-parse', '--git-dir'],
                cwd=LLVM_DIR, shell=use_shell).decode().strip()
        if not os.path.isdir(git_dir):
            print('.git dir not found at "%s"' % git_dir, file=sys.stderr)
            return 1

        rev = subprocess.check_output(
                [git, 'rev-parse', '--short', 'HEAD'],
                cwd=git_dir, shell=use_shell).decode().strip()
        url = subprocess.check_output(
                [git, 'remote', 'get-url', 'origin'],
                cwd=git_dir, shell=use_shell).decode().strip()
        for name in args.name:
            vcsrevision_contents += '#define %s_REVISION "%s"\n' % (name, rev)
            vcsrevision_contents += '#define %s_REPOSITORY "%s"\n' % (name, url)
    else:
        for name in args.name:
            vcsrevision_contents += '#undef %s_REVISION\n' % name
            vcsrevision_contents += '#undef %s_REPOSITORY\n' % name

    # If the output already exists and is identical to what we'd write,
    # return to not perturb the existing file's timestamp.
    if os.path.exists(args.vcs_header) and \
            open(args.vcs_header).read() == vcsrevision_contents:
        return 0

    # http://neugierig.org/software/blog/2014/11/binary-revisions.html
    if args.depfile:
        build_dir = os.getcwd()
        with open(args.depfile, 'w') as depfile:
            depfile.write('%s: %s\n' % (
                args.vcs_header,
                os.path.relpath(os.path.join(git_dir, 'logs', 'HEAD'),
                                build_dir)))
    open(args.vcs_header, 'w').write(vcsrevision_contents)


if __name__ == '__main__':
    sys.exit(main())
