# Copyright 2012 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.

# This file contains common function definitions for various other shell
# scripts in this directory. It is not meant to be executed by itself.

# Important: before including this file, the following variables must be set:
# - BRANCHNAME
# - PERSISTFILE_BASENAME

TEMP_BRANCH=$BRANCHNAME-temporary-branch-created-by-script
VERSION_FILE="src/version.cc"
CHANGELOG_ENTRY_FILE="$PERSISTFILE_BASENAME-changelog-entry"
PATCH_FILE="$PERSISTFILE_BASENAME-patch"
COMMITMSG_FILE="$PERSISTFILE_BASENAME-commitmsg"
TRUNK_REVISION_FILE="$PERSISTFILE_BASENAME-trunkrevision"
START_STEP=0
CURRENT_STEP=0

die() {
  [[ -n "$1" ]] && echo "Error: $1"
  echo "Exiting."
  exit 1
}

confirm() {
  echo -n "$1 [Y/n] "
  read ANSWER
  if [[ -z "$ANSWER" || "$ANSWER" == "Y" || "$ANSWER" == "y" ]] ; then
    return 0
  else
    return 1
  fi
}

delete_branch() {
  local MATCH=$(git branch | grep "$1" | awk '{print $NF}' | grep -x $1)
  if [ "$MATCH" == "$1" ] ; then
    confirm "Branch $1 exists, do you want to delete it?"
    if [ $? -eq 0 ] ; then
      git branch -D $1 || die "Deleting branch '$1' failed."
      echo "Branch $1 deleted."
    else
      die "Can't continue. Please delete branch $1 and try again."
    fi
  fi
}

# Persist and restore variables to support canceling/resuming execution
# of this script.
persist() {
  local VARNAME=$1
  local FILE="$PERSISTFILE_BASENAME-$VARNAME"
  local VALUE="${!VARNAME}"
  if [ -z "$VALUE" ] ; then
    VALUE="__EMPTY__"
  fi
  echo "$VALUE" > $FILE
}

restore() {
  local VARNAME=$1
  local FILE="$PERSISTFILE_BASENAME-$VARNAME"
  local VALUE="$(cat $FILE)"
  [[ -z "$VALUE" ]] && die "Variable '$VARNAME' could not be restored."
  if [ "$VALUE" == "__EMPTY__" ] ; then
    VALUE=""
  fi
  eval "$VARNAME=\"$VALUE\""
}

restore_if_unset() {
  local VARNAME=$1
  [[ -z "${!VARNAME}" ]] && restore "$VARNAME"
}

initial_environment_checks() {
  # Cancel if this is not a git checkout.
  [[ -d .git ]] \
    || die "This is not a git checkout, this script won't work for you."

  # Cancel if EDITOR is unset or not executable.
  [[ -n "$EDITOR" && -x "$(which $EDITOR)" ]] \
    || die "Please set your EDITOR environment variable, you'll need it."
}

common_prepare() {
  # Check for a clean workdir.
  [[ -z "$(git status -s -uno)" ]] \
    || die "Workspace is not clean. Please commit or undo your changes."

  # Persist current branch.
  CURRENT_BRANCH=$(git status -s -b -uno | grep "^##" | awk '{print $2}')
  persist "CURRENT_BRANCH"

  # Fetch unfetched revisions.
  git svn fetch || die "'git svn fetch' failed."

  # Get ahold of a safe temporary branch and check it out.
  if [ "$CURRENT_BRANCH" != "$TEMP_BRANCH" ] ; then
    delete_branch $TEMP_BRANCH
    git checkout -b $TEMP_BRANCH
  fi

  # Delete the branch that will be created later if it exists already.
  delete_branch $BRANCHNAME
}

common_cleanup() {
  restore_if_unset "CURRENT_BRANCH"
  git checkout -f $CURRENT_BRANCH
  [[ "$TEMP_BRANCH" != "$CURRENT_BRANCH" ]] && git branch -D $TEMP_BRANCH
  [[ "$BRANCHNAME" != "$CURRENT_BRANCH" ]] && git branch -D $BRANCHNAME
  # Clean up all temporary files.
  rm -f "$PERSISTFILE_BASENAME"*
}

# These two functions take a prefix for the variable names as first argument.
read_and_persist_version() {
  for v in MAJOR_VERSION MINOR_VERSION BUILD_NUMBER PATCH_LEVEL; do
    VARNAME="$1${v%%_*}"
    VALUE=$(grep "#define $v" "$VERSION_FILE" | awk '{print $NF}')
    eval "$VARNAME=\"$VALUE\""
    persist "$VARNAME"
  done
}
restore_version_if_unset() {
  for v in MAJOR MINOR BUILD PATCH; do
    restore_if_unset "$1$v"
  done
}

upload_step() {
  let CURRENT_STEP+=1
  if [ $START_STEP -le $CURRENT_STEP ] ; then
    echo ">>> Step $CURRENT_STEP: Upload for code review."
    echo -n "Please enter the email address of a V8 reviewer for your patch: "
    read REVIEWER
    git cl upload -r "$REVIEWER" --send-mail \
      || die "'git cl upload' failed, please try again."
  fi
}

wait_for_lgtm() {
  echo "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."
  unset ANSWER
  while [ "$ANSWER" != "LGTM" ] ; do
    [[ -n "$ANSWER" ]] && echo "That was not 'LGTM'."
    echo -n "> "
    read ANSWER
  done
}

wait_for_resolving_conflicts() {
  echo "Applying the patch \"$1\" failed. Either type \"ABORT<Return>\", or \
resolve the conflicts, stage *all* touched files with 'git add', and \
type \"RESOLVED<Return>\""
  unset ANSWER
  while [ "$ANSWER" != "RESOLVED" ] ; do
    [[ "$ANSWER" == "ABORT" ]] && die "Applying the patch failed."
    [[ -n "$ANSWER" ]] && echo "That was not 'RESOLVED' or 'ABORT'."
    echo -n "> "
    read ANSWER
  done
}

# Takes a file containing the patch to apply as first argument.
apply_patch() {
  git apply --index --reject $REVERSE_PATCH "$1" || \
    wait_for_resolving_conflicts "$1";
}
