#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import subprocess
import sys


def GetArgs():
  parser = argparse.ArgumentParser(
      description="Finds a commit that a given patch can be applied to. "
                  "Does not actually apply the patch or modify your checkout "
                  "in any way.")
  parser.add_argument("patch_file", help="Patch file to match")
  parser.add_argument(
      "--branch", "-b", default="origin/master", type=str,
      help="Git tree-ish where to start searching for commits, "
           "default: %(default)s")
  parser.add_argument(
      "--limit", "-l", default=500, type=int,
      help="Maximum number of commits to search, default: %(default)s")
  parser.add_argument(
      "--verbose", "-v", default=False, action="store_true",
      help="Print verbose output for your entertainment")
  return parser.parse_args()


def FindFilesInPatch(patch_file):
  files = {}
  next_file = ""
  with open(patch_file) as patch:
    for line in patch:
      if line.startswith("diff --git "):
        # diff --git a/src/objects.cc b/src/objects.cc
        words = line.split()
        assert words[2].startswith("a/") and len(words[2]) > 2
        next_file = words[2][2:]
      elif line.startswith("index "):
        # index add3e61..d1bbf6a 100644
        hashes = line.split()[1]
        old_hash = hashes.split("..")[0]
        if old_hash.startswith("0000000"): continue  # Ignore new files.
        files[next_file] = old_hash
  return files


def GetGitCommitHash(treeish):
  cmd = ["git", "log", "-1", "--format=%H", treeish]
  return subprocess.check_output(cmd).strip()


def CountMatchingFiles(commit, files):
  matched_files = 0
  # Calling out to git once and parsing the result Python-side is faster
  # than calling 'git ls-tree' for every file.
  cmd = ["git", "ls-tree", "-r", commit] + [f for f in files]
  output = subprocess.check_output(cmd)
  for line in output.splitlines():
    # 100644 blob c6d5daaa7d42e49a653f9861224aad0a0244b944      src/objects.cc
    _, _, actual_hash, filename = line.split()
    expected_hash = files[filename]
    if actual_hash.startswith(expected_hash): matched_files += 1
  return matched_files


def FindFirstMatchingCommit(start, files, limit, verbose):
  commit = GetGitCommitHash(start)
  num_files = len(files)
  if verbose: print(">>> Found %d files modified by patch." % num_files)
  for _ in range(limit):
    matched_files = CountMatchingFiles(commit, files)
    if verbose: print("Commit %s matched %d files" % (commit, matched_files))
    if matched_files == num_files:
      return commit
    commit = GetGitCommitHash("%s^" % commit)
  print("Sorry, no matching commit found. "
        "Try running 'git fetch', specifying the correct --branch, "
        "and/or setting a higher --limit.")
  sys.exit(1)


if __name__ == "__main__":
  args = GetArgs()
  files = FindFilesInPatch(args.patch_file)
  commit = FindFirstMatchingCommit(args.branch, files, args.limit, args.verbose)
  if args.verbose:
    print(">>> Matching commit: %s" % commit)
    print(subprocess.check_output(["git", "log", "-1", commit]))
    print(">>> Kthxbai.")
  else:
    print(commit)
