#!/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: <repo-path> <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 last release tag.
#  - A longer string with the project name, the software version number, and
#    git commit information for this release.
# The string contents are escaped as necessary.

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

# Regex to match the SPIR-V version tag.
# Example of matching tags:
#  - v2020.1
#  - v2020.1-dev
#  - v2020.1.rc1
VERSION_REGEX = re.compile(r'^v(\d+)\.(\d+)(-dev|rc\d+)?$')

# Format of the output generated by this script. Example:
# "v2023.1", "SPIRV-Tools v2023.1 0fc5526f2b01a0cc89192c10cf8bef77f1007a62, 2023-01-18T14:51:49"
OUTPUT_FORMAT = '"{version_tag}", "SPIRV-Tools {version_tag} {description}"\n'

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.
    """
    try:
      p = subprocess.Popen(cmd,
                           cwd=directory,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
      (stdout, stderr) = p.communicate()
      if p.returncode != 0:
        logging.error('Failed to run "{}" in "{}": {}'.format(cmd, directory, stderr.decode()))
    except Exception as e:
        logging.error('Failed to run "{}" in "{}": {}'.format(cmd, directory, str(e)))
        return False, None
    return p.returncode == 0, stdout

def deduce_last_release(repo_path):
    """Returns a software version number parsed from git tags."""

    success, tag_list = command_output(['git', 'tag', '--sort=-v:refname'], repo_path)
    if not success:
      return False, None

    latest_version_tag = None
    for tag in tag_list.decode().splitlines():
      if VERSION_REGEX.match(tag):
        latest_version_tag = tag
        break

    if latest_version_tag is None:
      logging.error("No tag matching version regex matching.")
      return False, None
    return True, latest_version_tag

def get_last_release_tuple(repo_path):
  success, version = deduce_last_release(repo_path)
  if not success:
    return False, None

  m = VERSION_REGEX.match(version)
  if len(m.groups()) != 3:
    return False, None
  return True, (int(m.groups()[0]), int(m.groups()[1]))

def deduce_current_release(repo_path):
  status, version_tuple = get_last_release_tuple(repo_path)
  if not status:
    return False, None

  last_release_tag = "v{}.{}-dev".format(*version_tuple)
  success, tag_list = command_output(['git', 'tag', '--contains'], repo_path)
  if success:
    if last_release_tag in set(tag_list.decode().splitlines()):
      return True, last_release_tag
  else:
    logging.warning("Could not check tags for commit. Assuming -dev version.")

  now_year = datetime.datetime.now().year
  if version_tuple[0] == now_year:
    version_tuple =  (now_year, version_tuple[1] + 1)
  else:
    version_tuple = (now_year, 1)

  return True, "v{}.{}-dev".format(*version_tuple)

def get_description_for_head(repo_path):
    """Returns a string describing the current Git HEAD version as descriptively
    as possible, in order of priority:
      - git describe output
      - git rev-parse HEAD output
      - "unknown-hash, <date>"
    """

    success, output = command_output(['git', 'describe'], repo_path)
    if not success:
      success, output = command_output(['git', 'rev-parse', 'HEAD'], repo_path)

    if success:
      # 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 output.rstrip().decode()

    # 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.
    if 'SOURCE_DATE_EPOCH' in os.environ:
      timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
      iso_date = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
    else:
      iso_date = datetime.datetime.now().isoformat()
    return "unknown_hash, {}".format(iso_date)

def main():
    FORMAT = '%(asctime)s %(message)s'
    logging.basicConfig(format="[%(asctime)s][%(levelname)-8s] %(message)s", datefmt="%H:%M:%S")
    if len(sys.argv) != 3:
        logging.error("usage: {} <repo-path> <output-file>".format(sys.argv[0]))
        sys.exit(1)

    repo_path = os.path.realpath(sys.argv[1])
    output_file_path = sys.argv[2]

    success, version = deduce_current_release(repo_path)
    if not success:
      logging.warning("Could not deduce latest release version from history.")
      version = "unknown_version"

    description = get_description_for_head(repo_path)
    content = OUTPUT_FORMAT.format(version_tag=version, description=description)

    # Escape file content.
    content.replace('"', '\\"')

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

    mkdir_p(os.path.dirname(output_file_path))
    with open(output_file_path, 'w') as f:
        f.write(content)

if __name__ == '__main__':
    main()
