#!/usr/bin/env python
# Copyright 2017 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.

"""
Use this script to cherry-pick a V8 commit to backport to a Node.js checkout.

Requirements:
  - Node.js checkout to backport to.
  - V8 checkout that contains the commit to cherry-pick.

Usage:
  $ backport_node.py <path_to_v8> <path_to_node> <commit-hash>

  This will apply the commit to <path_to_node>/deps/v8 and create a commit in
  the Node.js checkout, increment patch level, and copy over the original
  commit message.

Optional flags:
  --no-review  Run `gclient sync` on the V8 checkout before updating.
"""

import argparse
import os
import subprocess
import re
import sys

TARGET_SUBDIR = os.path.join("deps", "v8")
VERSION_FILE = os.path.join("include", "v8-version.h")
VERSION_PATTERN = r'(?<=#define V8_PATCH_LEVEL )\d+'

def FileToText(file_name):
  with open(file_name) as f:
    return f.read()

def TextToFile(text, file_name):
  with open(file_name, "w") as f:
    f.write(text)


def Clean(options):
  print ">> Cleaning target directory."
  subprocess.check_call(["git", "clean", "-fd"],
                        cwd = os.path.join(options.node_path, TARGET_SUBDIR))

def CherryPick(options):
  print ">> Apply patch."
  patch = subprocess.Popen(["git", "diff-tree", "-p", options.commit],
                           stdout=subprocess.PIPE, cwd=options.v8_path)
  patch.wait()
  try:
    subprocess.check_output(["git", "apply", "-3", "--directory=%s" % TARGET_SUBDIR],
                            stdin=patch.stdout, cwd=options.node_path)
  except:
    print ">> In another shell, please resolve patch conflicts"
    print ">> and `git add` affected files."
    print ">> Finally continue by entering RESOLVED."
    while raw_input("[RESOLVED]") != "RESOLVED":
      print ">> You need to type RESOLVED"

def UpdateVersion(options):
  print ">> Increment patch level."
  version_file = os.path.join(options.node_path, TARGET_SUBDIR, VERSION_FILE)
  text = FileToText(version_file)
  def increment(match):
    patch = int(match.group(0))
    return str(patch + 1)
  text = re.sub(VERSION_PATTERN, increment, text, flags=re.MULTILINE)
  TextToFile(text, version_file)

def CreateCommit(options):
  print ">> Creating commit."
  # Find short hash from source.
  shorthash = subprocess.check_output(
      ["git", "rev-parse", "--short", options.commit],
      cwd=options.v8_path).strip()

  # Commit message
  title = "deps: backport %s from upstream V8"  % shorthash
  body = subprocess.check_output(
      ["git", "log", options.commit, "-1", "--format=%B"],
      cwd=options.v8_path).strip()
  body = '\n'.join("  " + line for line in body.splitlines())

  message = title + "\n\nOriginal commit message:\n\n" + body

  # Create commit at target.
  review_message = "--no-edit" if options.no_review else "--edit"
  git_commands = [
    ["git", "checkout", "-b", "backport_%s" % shorthash],  # new branch
    ["git", "add", TARGET_SUBDIR],                         # add files
    ["git", "commit", "-m", message, review_message]       # new commit
  ]
  for command in git_commands:
    subprocess.check_call(command, cwd=options.node_path)

def ParseOptions(args):
  parser = argparse.ArgumentParser(description="Backport V8 commit to Node.js")
  parser.add_argument("v8_path", help="Path to V8 checkout")
  parser.add_argument("node_path", help="Path to Node.js checkout")
  parser.add_argument("commit", help="Commit to backport")
  parser.add_argument("--no-review", action="store_true",
                      help="Skip editing commit message")
  options = parser.parse_args(args)
  options.v8_path = os.path.abspath(options.v8_path)
  assert os.path.isdir(options.v8_path)
  options.node_path = os.path.abspath(options.node_path)
  assert os.path.isdir(options.node_path)
  return options

def Main(args):
  options = ParseOptions(args)
  Clean(options)
  try:
    CherryPick(options)
    UpdateVersion(options)
    CreateCommit(options)
  except:
    print ">> Failed. Resetting."
    subprocess.check_output(["git", "reset", "--hard"], cwd=options.node_path)
    raise

if __name__ == "__main__":
  Main(sys.argv[1:])
