#!/usr/bin/env python3
# Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import subprocess
import sys
import re
import r8_release

class Branch:
  def __init__(self, name, first, last=None):
    self.name = name
    self.first = first
    self.last = last # optional last for testing purposes.

  def origin(self):
    return "origin/%s" % self.name

  def last_or_origin(self):
    return self.last if self.last else self.origin()

  def __str__(self):
    return self.name

# The initial commit is the furthest back we need to search on main.
# Currently, it is the merge point of main onto 4.0.23-dev
MAIN = Branch('main', 'a2e203580aa00a36f85cd68d3d584b97aef34d59')
OLDEST_BRANCH_VERSION = (4, 0)
DEV_BRANCH_VERSION = [int(s) for s in r8_release.R8_DEV_BRANCH.split('.')]

# List of change ids that should not be reported.
IGNORED = [
    'I92d7bf3afbf609fdea21683941cfd15c90305cf2'
]

VERBOSE = False

# Helper to call and decode a shell command.
def run_cmd(cmd):
  if VERBOSE:
    print(' '.join(cmd))
  return subprocess.check_output(cmd).decode('UTF-8')

# Comparator on major and minor branch versions.
def branch_version_less_than(b1, b2):
  if b1[0] < b2[0]:
    return True
  if b1[0] == b2[0] and b1[1] < b2[1]:
    return True
  return False

# Find all release branches between OLDEST_BRANCH and DEV_BRANCH
def get_release_branches():
  # Release branches are assumed to be of the form 'origin/X.Y'
  out = run_cmd(['git', 'branch', '-r', '-l'])
  pattern = re.compile('origin/(\d+).(\d+)')
  releases = []
  for line in out.split('\n'):
    m = pattern.search(line.strip())
    if m:
      major = m.group(1)
      minor = m.group(2)
      if major and minor:
        candidate = (int(major), int(minor))
        if branch_version_less_than(candidate, OLDEST_BRANCH_VERSION):
          continue
        if branch_version_less_than(candidate, DEV_BRANCH_VERSION):
          releases.extend(find_dev_cutoff(candidate))
  return releases

# Find the most recent commit hash that is for a -dev version.
# This is the starting point for the map of commits after cutoff from main.
def find_dev_cutoff(branch_version):
  out = run_cmd([
      'git',
      'log',
      'origin/%d.%d' % branch_version,
      '--grep', 'Version .*-dev',
      '--pretty=oneline',
  ])
  # Format of output is: <hash> Version <version>-dev
  try:
    hash = out[0:out.index(' ')]
    return [Branch('%d.%d' % branch_version, hash)]
  except ValueError:
    throw_error("Failed to find dev cutoff for branch %d.%d" % branch_version)

# Build a map from each "Change-Id" hash to the hash of its commit.
def get_change_id_map(branch):
  out = run_cmd([
      'git',
      'log',
      '%s..%s' % (branch.first, branch.last_or_origin())
  ])
  map = {}
  current_commit = None
  for line in out.split('\n'):
    if line.startswith('commit '):
      current_commit = line[len('commit '):]
      assert len(current_commit) == 40
    elif line.strip().startswith('Change-Id: '):
      change_id = line.strip()[len('Change-Id: '):]
      assert len(change_id) == 41
      map[change_id] = current_commit
  return map

# Check if a specific commit is present on a specific branch.
def is_commit_in(commit, branch):
  out = run_cmd(['git', 'branch', '-r', branch.origin(), '--contains', commit])
  return out.strip() == branch.origin()

def main():
  found_errors = False
  # The main map is all commits back to the "init" point.
  main_map = get_change_id_map(MAIN)
  # Compute the release branches.
  release_branches = get_release_branches()
  # Populate the release maps with all commits after the last -dev point.
  release_maps = {}
  for branch in release_branches:
    release_maps[branch.name] = get_change_id_map(branch)
  # Each branch is then compared forwards with each subsequent branch.
  for i in range(len(release_branches)):
    branch = release_branches[i]
    newer_branches = release_branches[i+1:]
    if (len(newer_branches) == 0):
      print('Last non-dev release branch is %s, nothing to check.' % branch)
      continue
    print('Checking branch %s.' % branch)
    changes = release_maps[branch.name]
    cherry_picks_count = 0
    for change in changes.keys():
      is_cherry_pick = False
      missing_from = None
      commit_on_main = main_map.get(change)
      for newer_branch in newer_branches:
        if change in release_maps[newer_branch.name]:
          is_cherry_pick = True
          # If the change is in the release mappings check for holes.
          if missing_from:
            found_errors |= change_error(
                change,
                'Error: missing Change-Id %s on branch %s. '
                'Is present on %s and again on %s.' % (
                    change, missing_from, branch, newer_branch,
                ))
        elif commit_on_main:
          is_cherry_pick = True
          # The change is not in the non-dev part of the branch, so we need to
          # check that the fork from main included the change.
          if not is_commit_in(commit_on_main, newer_branch):
            found_errors |= change_error(
                change,
                'Error: missing Change-Id %s on branch %s. '
                'Is present on %s and on main as commit %s.' % (
                    change, newer_branch, branch, commit_on_main
                ))
        else:
          # The change is not on "main" so we just record for holes on releases.
          missing_from = newer_branch
      if is_cherry_pick:
        cherry_picks_count += 1
    print('Found %d cherry-picks (out of %d commits).' % (
        cherry_picks_count, len(changes)))

  if found_errors:
    return 1
  return 0

def change_error(change, msg):
  if change in IGNORED:
    return False
  error(msg)
  return True

def throw_error(msg):
  raise ValueError(msg)

def error(msg):
  print(msg, file=sys.stderr)

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