#!/usr/bin/env python

# Copyright (c) 2016 Google Inc.
#
# 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.

# Updates an output file with version info unless the new content is the same
# as the existing content.
#
# Args: <changes-file> <output-file>
#
# The output file will contain a line of text consisting of two C source syntax
# string literals separated by a comma:
#  - The software version deduced from the given CHANGES file.
#  - A longer string with the project name, the software version number, and
#    git commit information for the CHANGES file's directory.  The commit
#    information is the output of "git describe" if that succeeds, or "git
#    rev-parse HEAD" if that succeeds, or otherwise a message containing the
#    phrase "unknown hash".
# The string contents are escaped as necessary.

import datetime
import errno
import os
import os.path
import re
import subprocess
import sys
import time


def mkdir_p(directory):
    """Make the directory, and all its ancestors as required.  Any of the
    directories are allowed to already exist."""

    if directory == "":
        # We're being asked to make the current directory.
        return

    try:
        os.makedirs(directory)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(directory):
            pass
        else:
            raise


def command_output(cmd, directory):
    """Runs a command in a directory and returns its standard output stream.

    Captures the standard error stream.

    Raises a RuntimeError if the command fails to launch or otherwise fails.
    """
    p = subprocess.Popen(cmd,
                         cwd=directory,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    (stdout, _) = p.communicate()
    if p.returncode != 0:
        raise RuntimeError('Failed to run %s in %s' % (cmd, directory))
    return stdout


def deduce_software_version(changes_file):
    """Returns a software version number parsed from the given CHANGES file.

    The CHANGES file describes most recent versions first.
    """

    # Match the first well-formed version-and-date line.
    # Allow trailing whitespace in the checked-out source code has
    # unexpected carriage returns on a linefeed-only system such as
    # Linux.
    pattern = re.compile(r'^(v\d+\.\d+(-dev)?) \d\d\d\d-\d\d-\d\d\s*$')
    with open(changes_file, mode='r') as f:
        for line in f.readlines():
            match = pattern.match(line)
            if match:
                return match.group(1)
    raise Exception('No version number found in {}'.format(changes_file))


def describe(directory):
    """Returns a string describing the current Git HEAD version as descriptively
    as possible.

    Runs 'git describe', or alternately 'git rev-parse HEAD', in directory.  If
    successful, returns the output; otherwise returns 'unknown hash, <date>'."""
    try:
        # decode() is needed here for Python3 compatibility. In Python2,
        # str and bytes are the same type, but not in Python3.
        # Popen.communicate() returns a bytes instance, which needs to be
        # decoded into text data first in Python3. And this decode() won't
        # hurt Python2.
        return command_output(['git', 'describe'], directory).rstrip().decode()
    except:
        try:
            return command_output(
                ['git', 'rev-parse', 'HEAD'], directory).rstrip().decode()
        except:
            # This is the fallback case where git gives us no information,
            # e.g. because the source tree might not be in a git tree.
            # In this case, usually use a timestamp.  However, to ensure
            # reproducible builds, allow the builder to override the wall
            # clock time with environment variable SOURCE_DATE_EPOCH
            # containing a (presumably) fixed timestamp.
            timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
            formatted = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
            return 'unknown hash, {}'.format(formatted)


def main():
    if len(sys.argv) != 3:
        print('usage: {} <changes-files> <output-file>'.format(sys.argv[0]))
        sys.exit(1)

    output_file = sys.argv[2]
    mkdir_p(os.path.dirname(output_file))

    software_version = deduce_software_version(sys.argv[1])
    directory = os.path.dirname(sys.argv[1])
    new_content = '"{}", "SPIRV-Tools {} {}"\n'.format(
        software_version, software_version,
        describe(directory).replace('"', '\\"'))

    if os.path.isfile(output_file):
        with open(output_file, 'r') as f:
            if new_content == f.read():
                return

    with open(output_file, 'w') as f:
        f.write(new_content)

if __name__ == '__main__':
    main()
