#!/usr/bin/env python3
# Copyright (C) 2020 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.
"""
Writes the perfetto_version{.gen.h, .ts} files.

This tool is run as part of a genrule from GN, SoonG and Bazel builds. It
generates a source header (or in the case of --ts_out a TypeScript file) that
contains:
- The version number (e.g. v9.0) obtained parsing the CHANGELOG file.
- The git HEAD's commit-ish (e.g. 6b330b772b0e973f79c70ba2e9bb2b0110c6715d)

The latter is concatenated to the version number to disambiguate builds made
from release tags vs builds made from the main branch vs UI builds made from the
ui-canary/ui-stable branch.
"""

import argparse
import json
import os
import re
import sys
import subprocess

# Note: PROJECT_ROOT is not accurate in bazel builds, where this script is
# executed in the bazel sandbox.
PROJECT_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
SCM_REV_NOT_AVAILABLE = 'N/A'


def get_latest_release(changelog_path):
  """Returns a string like 'v9.0'.

  It does so by searching the latest version mentioned in the CHANGELOG."""
  if not changelog_path:
    if os.path.exists('CHANGELOG'):
      changelog_path = 'CHANGELOG'
    else:
      changelog_path = os.path.join(PROJECT_ROOT, 'CHANGELOG')
  with open(changelog_path) as f:
    for line in f.readlines():
      m = re.match(r'^(v\d+[.]\d+)\s.*$', line)
      if m is not None:
        return m.group(1)
  raise Exception('Failed to fetch Perfetto version from %s' % changelog_path)


def get_git_sha1(commitish):
  """Returns the SHA1 of the provided commit-ish"""
  # Embedders / forks can override the SCM revision via env var so the
  # version string baked into the build identifies their checkout
  # instead of perfetto's git HEAD.
  override = os.environ.get('PERFETTO_VERSION_HEADER_OVERRIDE_SCM_REVISION')
  if override:
    return override
  commit_sha1 = SCM_REV_NOT_AVAILABLE
  git_dir = os.path.join(PROJECT_ROOT, '.git')
  if os.path.exists(git_dir):
    try:
      commit_sha1 = subprocess.check_output(['git', 'rev-parse', commitish],
                                            cwd=PROJECT_ROOT).strip().decode()
    except subprocess.CalledProcessError:
      pass
  return commit_sha1


def write_if_unchanged(path, content):
  prev_content = None
  if os.path.exists(path):
    with open(path, 'r') as fprev:
      prev_content = fprev.read()
  if prev_content == content:
    return 0
  with open(path, 'w') as fout:
    fout.write(content)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--check_git', action='store_true')
  parser.add_argument(
      '--no_git',
      action='store_true',
      help='Skips running git rev-parse, emits only the version from CHANGELOG')
  parser.add_argument('--cpp_out', help='Path of the generated .h file.')
  parser.add_argument('--ts_out', help='Path of the generated .ts file.')
  parser.add_argument('--stdout', help='Write to stdout', action='store_true')
  parser.add_argument(
      '--json', help='Emit {version, sha1} JSON to stdout', action='store_true')
  parser.add_argument('--changelog', help='Path to CHANGELOG.')
  args = parser.parse_args()

  if args.check_git:
    has_git = os.path.exists(os.path.join(PROJECT_ROOT, '.git', 'HEAD'))
    print('1' if has_git else '0')
    return 0

  release = get_latest_release(args.changelog)

  if args.no_git:
    head_sha1 = SCM_REV_NOT_AVAILABLE
  else:
    head_sha1 = get_git_sha1('HEAD')  # SCM_REV_NOT_AVAILABLE on failure.

  if head_sha1 == SCM_REV_NOT_AVAILABLE:
    version = release  # e.g., 'v9.0'.
  else:
    sha1_abbrev = head_sha1[:9]
    version = f'{release}-{sha1_abbrev}'  # e.g., 'v9.0-adeadbeef'.

  if args.cpp_out:
    guard = '%s_' % args.cpp_out.upper()
    guard = re.sub(r'[^\w]', '_', guard)
    lines = []
    lines.append('// Generated by %s' % os.path.basename(__file__))
    lines.append('')
    lines.append('#ifndef %s' % guard)
    lines.append('#define %s' % guard)
    lines.append('')
    lines.append('#define PERFETTO_VERSION_STRING() "%s"' % version)
    lines.append('#define PERFETTO_VERSION_SCM_REVISION() "%s"' % head_sha1)
    lines.append('')
    lines.append('#endif  // %s' % guard)
    lines.append('')
    content = '\n'.join(lines)
    write_if_unchanged(args.cpp_out, content)

  if args.ts_out:
    lines = []
    lines.append('export const VERSION = "%s";' % version)
    lines.append('export const SCM_REVISION = "%s";' % head_sha1)
    content = '\n'.join(lines)
    write_if_unchanged(args.ts_out, content)

  if args.stdout:
    print(version)

  if args.json:
    print(json.dumps({'version': version, 'sha1': head_sha1}))


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