#!/usr/bin/env python
# Copyright 2015 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 operator
import os
import re
from sets import Set
from subprocess import Popen, PIPE
import sys

def search_all_related_commits(
    git_working_dir, start_hash, until, separator, verbose=False):

  all_commits_raw = _find_commits_inbetween(
      start_hash, until, git_working_dir, verbose)
  if verbose:
    print "All commits between <of> and <until>: " + all_commits_raw

  # Adding start hash too
  all_commits = [start_hash]
  all_commits.extend(all_commits_raw.splitlines())
  all_related_commits = {}
  already_treated_commits = Set([])
  for commit in all_commits:
    if commit in already_treated_commits:
      continue

    related_commits = _search_related_commits(
        git_working_dir, commit, until, separator, verbose)
    if len(related_commits) > 0:
      all_related_commits[commit] = related_commits
      already_treated_commits.update(related_commits)

    already_treated_commits.update(commit)

  return all_related_commits

def _search_related_commits(
    git_working_dir, start_hash, until, separator, verbose=False):

  if separator:
    commits_between = _find_commits_inbetween(
        start_hash, separator, git_working_dir, verbose)
    if commits_between == "":
      return []

  # Extract commit position
  original_message = git_execute(
      git_working_dir,
      ["show", "-s", "--format=%B", start_hash],
      verbose)
  title = original_message.splitlines()[0]

  matches = re.search("(\{#)([0-9]*)(\})", original_message)

  if not matches:
    return []

  commit_position = matches.group(2)
  if verbose:
    print "1.) Commit position to look for: " + commit_position

  search_range = start_hash + ".." + until

  def git_args(grep_pattern):
    return [
      "log",
      "--reverse",
      "--grep=" + grep_pattern,
      "--format=%H",
      search_range,
    ]

  found_by_hash = git_execute(
      git_working_dir, git_args(start_hash), verbose).strip()

  if verbose:
    print "2.) Found by hash: " + found_by_hash

  found_by_commit_pos = git_execute(
      git_working_dir, git_args(commit_position), verbose).strip()

  if verbose:
    print "3.) Found by commit position: " + found_by_commit_pos

  # Replace brackets or else they are wrongly interpreted by --grep
  title = title.replace("[", "\\[")
  title = title.replace("]", "\\]")

  found_by_title = git_execute(
      git_working_dir, git_args(title), verbose).strip()

  if verbose:
    print "4.) Found by title: " + found_by_title

  hits = (
      _convert_to_array(found_by_hash) +
      _convert_to_array(found_by_commit_pos) +
      _convert_to_array(found_by_title))
  hits = _remove_duplicates(hits)

  if separator:
    for current_hit in hits:
      commits_between = _find_commits_inbetween(
          separator, current_hit, git_working_dir, verbose)
      if commits_between != "":
        return hits
    return []

  return hits

def _find_commits_inbetween(start_hash, end_hash, git_working_dir, verbose):
  commits_between = git_execute(
        git_working_dir,
        ["rev-list", "--reverse", start_hash + ".." + end_hash],
        verbose)
  return commits_between.strip()

def _convert_to_array(string_of_hashes):
  return string_of_hashes.splitlines()

def _remove_duplicates(array):
   no_duplicates = []
   for current in array:
    if not current in no_duplicates:
      no_duplicates.append(current)
   return no_duplicates

def git_execute(working_dir, args, verbose=False):
  command = ["git", "-C", working_dir] + args
  if verbose:
    print "Git working dir: " + working_dir
    print "Executing git command:" + str(command)
  p = Popen(args=command, stdin=PIPE,
            stdout=PIPE, stderr=PIPE)
  output, err = p.communicate()
  rc = p.returncode
  if rc != 0:
    raise Exception(err)
  if verbose:
    print "Git return value: " + output
  return output

def _pretty_print_entry(hash, git_dir, pre_text, verbose):
  text_to_print = git_execute(
      git_dir,
      ["show",
       "--quiet",
       "--date=iso",
       hash,
       "--format=%ad # %H # %s"],
      verbose)
  return pre_text + text_to_print.strip()

def main(options):
    all_related_commits = search_all_related_commits(
        options.git_dir,
        options.of[0],
        options.until[0],
        options.separator,
        options.verbose)

    sort_key = lambda x: (
        git_execute(
            options.git_dir,
            ["show", "--quiet", "--date=iso", x, "--format=%ad"],
            options.verbose)).strip()

    high_level_commits = sorted(all_related_commits.keys(), key=sort_key)

    for current_key in high_level_commits:
      if options.prettyprint:
        yield _pretty_print_entry(
            current_key,
            options.git_dir,
            "+",
            options.verbose)
      else:
        yield "+" + current_key

      found_commits = all_related_commits[current_key]
      for current_commit in found_commits:
        if options.prettyprint:
          yield _pretty_print_entry(
              current_commit,
              options.git_dir,
              "| ",
              options.verbose)
        else:
          yield "| " + current_commit

if __name__ == "__main__":  # pragma: no cover
  parser = argparse.ArgumentParser(
      "This tool analyzes the commit range between <of> and <until>. "
      "It finds commits which belong together e.g. Implement/Revert pairs and "
      "Implement/Port/Revert triples. All supplied hashes need to be "
      "from the same branch e.g. master.")
  parser.add_argument("-g", "--git-dir", required=False, default=".",
                        help="The path to your git working directory.")
  parser.add_argument("--verbose", action="store_true",
      help="Enables a very verbose output")
  parser.add_argument("of", nargs=1,
      help="Hash of the commit to be searched.")
  parser.add_argument("until", nargs=1,
      help="Commit when searching should stop")
  parser.add_argument("--separator", required=False,
      help="The script will only list related commits "
            "which are separated by hash <--separator>.")
  parser.add_argument("--prettyprint", action="store_true",
      help="Pretty prints the output")

  args = sys.argv[1:]
  options = parser.parse_args(args)
  for current_line in main(options):
    print current_line
