#! /usr/bin/env zsh -euo pipefail

# Check if exactly one argument was passed: the new version.
if (( $# != 1 )) || [[ "$1" == "--help" ]]; then
  >&2 {
    echo "Usage: $0 <version>"
    echo "  version: The new version, e.g., 2021.04.29 or 2021.04.29-rc1"
  }
  exit 1
fi

# Check if all required tools are available.
for binary in 'cmake' 'gh' 'rsync' 'git' 'perl'; do
  if ! command -v "${binary}" 2>&1 >/dev/null; then
    >&2 echo "Error: ${binary} not in PATH"
    exit 1
  fi
done

# To simplify this script, we require a clean working directoy.
if ! [ -z "$(git status --porcelain)" ]; then
  >&2 echo "Error: working directory unclean"
  exit 1
fi

# Determine source and build directory.
source_dir="$(git -C "$(dirname "$0:A")" rev-parse --show-toplevel)"
build_dir=$(mktemp -d 2>/dev/null || mktemp -d -t "build-${new_version}")

# Determine the last version including release candidates, the last version
# excluding release candidates and the new version.
last_rc_version="$(git -C "${source_dir}" describe --abbrev=0)"
last_version="$(git -C "${source_dir}" describe --abbrev=0 --exclude='*-rc*')"
new_version="$1"

# Check that the new version does not exist already.
if [ -d "${source_dir}/changelog/${new_version}" ]; then
  >&2 echo "Error: changelog/${new_version} already exists"
  exit 1
fi

# Create a new branch that bases off of current origin/master.
git fetch origin master
git switch -C "topic/release-${new_version}" origin/master

# Change the fallback version.
perl -i -pe "s/${last_rc_version}/${new_version}/g" \
  "${source_dir}/cmake/VASTVersionFallback.cmake"

# If the new version is not a release candidate, change mentions of the vesion
# in README.md and pyvast/setup.py as well.
if [[ "${new_version}" != *"-rc"* ]]; then
  perl -i -pe "s/${last_version}/${new_version}/g" "${source_dir}/README.md"
  perl -i -pe "s/${last_version}/${new_version}/g" \
    "${source_dir}/pyvast/setup.py"
fi

# Copy the unreleased changelog directory.
if [ -d "${source_dir}/changelog/unreleased" ]; then
  for entry in "${source_dir}/changelog/unreleased/"**/*.md; do
    mv "$entry" "${entry/--*.md/.md}"
  done
  rsync -avzh "${source_dir}/changelog/unreleased/" \
    "${source_dir}/changelog/${new_version}"
  rm -r "${source_dir}/changelog/unreleased"
fi

# If the previous release was an rc as well, merge the changelog directories.
if [[ "${last_rc_version}" == *"-rc"* ]]; then
  if [ -d "${source_dir}/changelog/${last_rc_version}" ]; then
    rsync -avzh "${source_dir}/changelog/${last_rc_version}/" \
      "${source_dir}/changelog/${new_version}"
    rm -r "${source_dir}/changelog/${last_rc_version}"
  fi
fi

# Configure the build and update the local changelog.
cmake -B "${build_dir}"
cmake --build "${build_dir}" --target update-changelog

# Commit and open a PR against tenzir/vast.
pushd "${source_dir}"
git add --all
git commit -m "Prepare repository for VAST ${new_version}"
gh pr create --web
popd

# Switch back to the branch we started on.
git switch -
