#!/bin/bash

# Copyright 2015 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eu

# Some common method for release scripts

# A release candidate is created from a branch named "release-%name%"
# where %name% is the name of the release. Once promoted to a release,
# A tag %name% will be created from this branch and the corresponding
# branch removed.
# The last commit of the release branch is always a commit containing
# the release notes in the commit message and updating the CHANGELOG.md.
# This last commit will be cherry-picked back in the master branch
# when the release candidate is promoted to a release.
# To follow tracks and to support how CI systems fetch the refs, we
# store two commit notes: the release name and the candidate number.

# Returns the branch name of the current git repository
function git_get_branch() {
  git symbolic-ref --short HEAD
}

# Show the commit message of the ref specified in argument
function git_commit_msg() {
  git show -s --pretty=format:%B "$@"
}

# Extract the release candidate number from the git notes
function get_release_candidate() {
  git notes --ref=release-candidate show "$@" 2>/dev/null | xargs echo || true
}

# Extract the release name from the git notes
function get_release_name() {
  git notes --ref=release show "$@" 2>/dev/null | xargs echo || true
}

# Get the short hash of a commit
function git_commit_shorthash() {
  git rev-parse --short "${1}"
}

# Get the subject (first line of the commit message) of a commit
function git_commit_subject() {
  git show -s --pretty=format:%s "$@"
}

# Get the list of commit hashes between two revisions
function git_log_hash() {
  local baseline="$1"
  local head="$2"
  shift 2
  git log --pretty=format:%H "${baseline}".."${head}" "$@"
}

# Extract the full release name from the git notes
function get_full_release_name() {
  local name="$(get_release_name "$@")"
  local rc="$(get_release_candidate "$@")"
  if [ -n "${rc}" ]; then
    echo "${name}rc${rc}"
  else
    echo "${name}"
  fi
}

# Extract the release notes from the git notes
function get_release_notes() {
  git notes --ref=release-notes show "$@" 2>/dev/null || true
}

# Returns the info from the branch of the release. It is the current branch
# but it errors out if the current branch is not a release branch. This
# method returns the tag of the release and the number of the current
# candidate in this release.
function get_release_branch() {
  local branch_name=$(git_get_branch)
  if [ -z "$(get_release_name)" -o -z "$(get_release_candidate)" ]; then
    echo "Not a release branch: ${branch_name}." >&2
    exit 1
  fi
  echo "${branch_name}"
}

# fmt behaves differently on *BSD and on GNU/Linux, use fold.
function wrap_text() {
  fold -s -w $1 | sed 's/ *$//'
}

# Create the revision information given a list of commits. The first
# commit should be the baseline, and the other ones are the cherry-picks.
# The result is of the form:
# Baseline: BASELINE_COMMIT
#
# Cherry picks:
#    + CHERRY_PICK1: commit message summary of the CHERRY_PICK1. This
#                    message will be wrapped into 70 columns.
#    + CHERRY_PICK2: commit message summary of the CHERRY_PICK2.
function create_revision_information() {
  echo "Baseline: $(git_commit_shorthash "${1}")"
  local first=1
  shift
  while [ -n "${1-}" ]; do
    if [[ "$first" -eq 1 ]]; then
      echo -e "\nCherry picks:"
      first=0
    fi
    local hash="$(git_commit_shorthash "${1}")"
    local subject="$(git_commit_subject $hash)"
    local lines=$(echo "$subject" | wrap_text 56)  # 14 leading spaces.
    echo "   + $hash: $lines" | head -1
    echo "$lines" | tail -n +2 | sed 's/^/              /'
    shift
  done
}

# Get the master commit
# Some machine might not have a "master" branch, use "origin/master" in that case
function get_master_ref() {
  git rev-parse --verify master 2>/dev/null || git rev-parse --verify origin/master
}

# Get the baseline of master.
# Args: $1: release branch, default to HEAD
function get_release_baseline() {
  git merge-base $(get_master_ref) "${1:-HEAD}"
}

# Get the list of cherry-picks since master
# Args:
#   $1: branch, default to HEAD
#   $2: baseline change, default to $(get_release_baseline $1)
function get_cherrypicks() {
  local branch="${1:-HEAD}"
  local master=$(get_master_ref)
  local baseline="${2:-$(get_release_baseline "${branch}")}"
  # List of changes since the baseline on the release branch
  local changes="$(git_log_hash "${baseline}" "${branch}" --reverse)"
  # List of changes since the baseline on the master branch, and their patch-id
  local master_changes="$(git_log_hash "${baseline}" "${master}" | xargs git show | git patch-id)"
  # Now for each changes on the release branch
  for i in ${changes}; do
    # Find the change with the same patch-id on the master branch
    echo "${master_changes}" \
      | grep "^$(git show "$i" | git patch-id | cut -d " " -f 1)" \
      | cut -d " " -f 2
  done
}

# Generate the title of the release with the date from the release name ($1).
function get_release_title() {
  echo "Release ${1} ($(date +%Y-%m-%d))"
}

# Generate the release message to be added to the changelog
# from the release notes for release $1
function generate_release_message() {
  local release_name="$1"
  local branch="${2:-HEAD}"
  local baseline="$(get_release_baseline "${branch}")"
  local cherrypicks="$(get_cherrypicks "${branch}" "${baseline}")"

cat <<EOF
$(get_release_title "$release_name")

$(create_revision_information $baseline $cherrypicks)

$(get_release_notes "${branch}")
EOF
}

# Returns the release notes for the CHANGELOG.md taken from either from
# the notes for a release candidate or from the commit message for a
# full release.
function get_full_release_notes() {
  local release_name="$(get_full_release_name "$@")"

  if [[ "${release_name}" =~ rc[0-9]+$ ]]; then
    # Release candidate, we need to generate from the notes
    generate_release_message "${release_name}" "$@"
  else
    # Full release, returns the commit message
    git_commit_msg "$@"
  fi
}

# Merge three release notes using branch $1 as a base
# Args:
#   $1 the branch name to use to play on
#   $2 the new generated release notes
#   $3 the last generated release notes
#   $4 the last edited release notes
function merge_release_notes() {
  local branch_name="$1"
  local relnotes="$2"
  local last_relnotes="$3"
  local last_savedrelnotes="$4"
  if [ "${last_relnotes}" == "${last_savedrelnotes}" ]; then
    echo "${relnotes}"
  else
    # Merge the three release notes, use git merge for it
    git checkout -q -b "${branch_name}-merge-notes-1"
    echo "${last_relnotes}" >.relnotes
    git add .relnotes
    git commit -q -m "last_relnotes" --allow-empty
    echo "${last_savedrelnotes}" >.relnotes
    git add .relnotes
    git commit -q -m "last_savedrelnotes" --allow-empty
    git checkout -q -b "${branch_name}-merge-notes-2" HEAD~
    echo "${relnotes}" >.relnotes
    git add .relnotes
    git commit -q -m "relnotes" --allow-empty
    git merge -q --no-commit "${branch_name}-merge-notes-1" &>/dev/null || true
    cat .relnotes

    # Clean-up
    git merge --abort || true &>/dev/null
    git checkout -q "${branch_name}"
    git branch -D ${branch_name}-merge-notes-{1,2} >/dev/null
  fi
}
