#!/usr/bin/env python
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import re
import subprocess
import sys

PERSISTFILE_BASENAME = "PERSISTFILE_BASENAME"
TEMP_BRANCH = "TEMP_BRANCH"
BRANCHNAME = "BRANCHNAME"
DOT_GIT_LOCATION = "DOT_GIT_LOCATION"
VERSION_FILE = "VERSION_FILE"
CHANGELOG_FILE = "CHANGELOG_FILE"
CHANGELOG_ENTRY_FILE = "CHANGELOG_ENTRY_FILE"
COMMITMSG_FILE = "COMMITMSG_FILE"
PATCH_FILE = "PATCH_FILE"


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


def AppendToFile(text, file_name):
  with open(file_name, "a") as f:
    f.write(text)


def LinesInFile(file_name):
  with open(file_name) as f:
    for line in f:
      yield line


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


def MSub(rexp, replacement, text):
  return re.sub(rexp, replacement, text, flags=re.MULTILINE)


def GetLastChangeLogEntries(change_log_file):
  result = []
  for line in LinesInFile(change_log_file):
    if re.search(r"^\d{4}-\d{2}-\d{2}:", line) and result: break
    result.append(line)
  return "".join(result)


# Some commands don't like the pipe, e.g. calling vi from within the script or
# from subscripts like git cl upload.
def Command(cmd, args="", prefix="", pipe=True):
  cmd_line = "%s %s %s" % (prefix, cmd, args)
  print "Command: %s" % cmd_line
  try:
    if pipe:
      return subprocess.check_output(cmd_line, shell=True)
    else:
      return subprocess.check_call(cmd_line, shell=True)
  except subprocess.CalledProcessError:
    return None


# Wrapper for side effects.
class SideEffectHandler(object):
  def Command(self, cmd, args="", prefix="", pipe=True):
    return Command(cmd, args, prefix, pipe)

  def ReadLine(self):
    return sys.stdin.readline().strip()

DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()


class Step(object):
  def __init__(self, text="", requires=None):
    self._text = text
    self._number = -1
    self._requires = requires
    self._side_effect_handler = DEFAULT_SIDE_EFFECT_HANDLER

  def SetNumber(self, number):
    self._number = number

  def SetConfig(self, config):
    self._config = config

  def SetState(self, state):
    self._state = state

  def SetOptions(self, options):
    self._options = options

  def SetSideEffectHandler(self, handler):
    self._side_effect_handler = handler

  def Config(self, key):
    return self._config[key]

  def Run(self):
    assert self._number >= 0
    assert self._config is not None
    assert self._state is not None
    assert self._side_effect_handler is not None
    if self._requires:
      self.RestoreIfUnset(self._requires)
      if not self._state[self._requires]:
        return
    print ">>> Step %d: %s" % (self._number, self._text)
    self.RunStep()

  def RunStep(self):
    raise NotImplementedError

  def ReadLine(self):
    return self._side_effect_handler.ReadLine()

  def Git(self, args="", prefix="", pipe=True):
    return self._side_effect_handler.Command("git", args, prefix, pipe)

  def Editor(self, args):
    return self._side_effect_handler.Command(os.environ["EDITOR"], args,
                                             pipe=False)

  def Die(self, msg=""):
    if msg != "":
      print "Error: %s" % msg
    print "Exiting"
    raise Exception(msg)

  def Confirm(self, msg):
    print "%s [Y/n] " % msg,
    answer = self.ReadLine()
    return answer == "" or answer == "Y" or answer == "y"

  def DeleteBranch(self, name):
    git_result = self.Git("branch").strip()
    for line in git_result.splitlines():
      if re.match(r".*\s+%s$" % name, line):
        msg = "Branch %s exists, do you want to delete it?" % name
        if self.Confirm(msg):
          if self.Git("branch -D %s" % name) is None:
            self.Die("Deleting branch '%s' failed." % name)
          print "Branch %s deleted." % name
        else:
          msg = "Can't continue. Please delete branch %s and try again." % name
          self.Die(msg)

  def Persist(self, var, value):
    value = value or "__EMPTY__"
    TextToFile(value, "%s-%s" % (self._config[PERSISTFILE_BASENAME], var))

  def Restore(self, var):
    value = FileToText("%s-%s" % (self._config[PERSISTFILE_BASENAME], var))
    value = value or self.Die("Variable '%s' could not be restored." % var)
    return "" if value == "__EMPTY__" else value

  def RestoreIfUnset(self, var_name):
    if self._state.get(var_name) is None:
      self._state[var_name] = self.Restore(var_name)

  def InitialEnvironmentChecks(self):
    # Cancel if this is not a git checkout.
    if not os.path.exists(self._config[DOT_GIT_LOCATION]):
      self.Die("This is not a git checkout, this script won't work for you.")

    # Cancel if EDITOR is unset or not executable.
    if (not os.environ.get("EDITOR") or
        Command("which", os.environ["EDITOR"]) is None):
      self.Die("Please set your EDITOR environment variable, you'll need it.")

  def CommonPrepare(self):
    # Check for a clean workdir.
    if self.Git("status -s -uno").strip() != "":
      self.Die("Workspace is not clean. Please commit or undo your changes.")

    # Persist current branch.
    current_branch = ""
    git_result = self.Git("status -s -b -uno").strip()
    for line in git_result.splitlines():
      match = re.match(r"^## (.+)", line)
      if match:
        current_branch = match.group(1)
        break
    self.Persist("current_branch", current_branch)

    # Fetch unfetched revisions.
    if self.Git("svn fetch") is None:
      self.Die("'git svn fetch' failed.")

    # Get ahold of a safe temporary branch and check it out.
    if current_branch != self._config[TEMP_BRANCH]:
      self.DeleteBranch(self._config[TEMP_BRANCH])
      self.Git("checkout -b %s" % self._config[TEMP_BRANCH])

    # Delete the branch that will be created later if it exists already.
    self.DeleteBranch(self._config[BRANCHNAME])

  def CommonCleanup(self):
    self.RestoreIfUnset("current_branch")
    self.Git("checkout -f %s" % self._state["current_branch"])
    if self._config[TEMP_BRANCH] != self._state["current_branch"]:
      self.Git("branch -D %s" % self._config[TEMP_BRANCH])
    if self._config[BRANCHNAME] != self._state["current_branch"]:
      self.Git("branch -D %s" % self._config[BRANCHNAME])

    # Clean up all temporary files.
    Command("rm", "-f %s*" % self._config[PERSISTFILE_BASENAME])

  def ReadAndPersistVersion(self, prefix=""):
    def ReadAndPersist(var_name, def_name):
      match = re.match(r"^#define %s\s+(\d*)" % def_name, line)
      if match:
        value = match.group(1)
        self.Persist("%s%s" % (prefix, var_name), value)
        self._state["%s%s" % (prefix, var_name)] = value
    for line in LinesInFile(self._config[VERSION_FILE]):
      for (var_name, def_name) in [("major", "MAJOR_VERSION"),
                                   ("minor", "MINOR_VERSION"),
                                   ("build", "BUILD_NUMBER"),
                                   ("patch", "PATCH_LEVEL")]:
        ReadAndPersist(var_name, def_name)

  def RestoreVersionIfUnset(self, prefix=""):
    for v in ["major", "minor", "build", "patch"]:
      self.RestoreIfUnset("%s%s" % (prefix, v))

  def WaitForLGTM(self):
    print ("Please wait for an LGTM, then type \"LGTM<Return>\" to commit "
           "your change. (If you need to iterate on the patch or double check "
           "that it's sane, do so in another shell, but remember to not "
           "change the headline of the uploaded CL.")
    answer = ""
    while answer != "LGTM":
      print "> ",
      answer = self.ReadLine()
      if answer != "LGTM":
        print "That was not 'LGTM'."

  def WaitForResolvingConflicts(self, patch_file):
    print("Applying the patch \"%s\" failed. Either type \"ABORT<Return>\", "
          "or resolve the conflicts, stage *all* touched files with "
          "'git add', and type \"RESOLVED<Return>\"")
    answer = ""
    while answer != "RESOLVED":
      if answer == "ABORT":
        self.Die("Applying the patch failed.")
      if answer != "":
        print "That was not 'RESOLVED' or 'ABORT'."
      print "> ",
      answer = self.ReadLine()

  # Takes a file containing the patch to apply as first argument.
  def ApplyPatch(self, patch_file, reverse_patch=""):
    args = "apply --index --reject %s \"%s\"" % (reverse_patch, patch_file)
    if self.Git(args) is None:
      self.WaitForResolvingConflicts(patch_file)


class UploadStep(Step):
  def __init__(self):
    Step.__init__(self, "Upload for code review.")

  def RunStep(self):
    print "Please enter the email address of a V8 reviewer for your patch: ",
    reviewer = self.ReadLine()
    args = "cl upload -r \"%s\" --send-mail" % reviewer
    if self.Git(args,pipe=False) is None:
      self.Die("'git cl upload' failed, please try again.")
