#!/usr/bin/env bash

source "$(dirname "$0")/release-lib.sh"
check_requirements

#-------------------------------------------------------------------------------
function usage() {
   echo "Make a Kong release using this script:"
   echo ""
   echo "Usage:"
   echo
   if [ "$version" = "<x.y.z>" ]
   then
      echo "     List executed steps for a given release"
      echo "        $0 $version $1 $3"
      echo
   fi
   if ! [[ $prerelease =~ alpha ]]
   then
       step "check_milestone"      "ensure all PRs marked on the release milestone are 100% merged"
       step "check_dependencies"   "ensure all kong dependencies are bumped in the rockspec"
   fi
   step "create"               "create the branch"
   step "write_changelog"      "prepare the changelog"
   step "commit_changelog"     "commit the changelog"
   step "update_copyright"     "update copyright file"
   step "update_admin_api_def" "update Admin API definition"
   step "version_bump"         "bump and commit the version number"
   step "submit_release_pr"    "push and submit a release PR"
   step "merge"                "merge, tag and sign the release"

   if [[ $prerelease =~ alpha ]]
   then
       echo -e "${red}${bold}Check whether you need any of the following steps for this alpha release${nocolor}"
       echo
   fi

   step "docs_pr"              "push and submit a docs.konghq.com PR for the release"
   step "approve_docker"       "get humans to review and approve machine-provided pull request at docker-kong repo"
   step "merge_docker"         "merge, tag and sign Kong's docker-kong PR"
   step "submit_docker"        "submit a PR to docker-library/official-images"
   step "merge_homebrew"       "humans approve and merge machine PR to homebrew-kong"
   step "upload_luarock"       "upload to LuaRocks" "<api-key>"
   step "merge_vagrant"        "humans approve and merge machine PR to kong-vagrant"
   step "merge_pongo"          "humans approve and merge machine PR to kong-pongo"
   step "announce"             "Get announcement messages for Kong Nation and Slack #general"

   #----------------------------------------------------------------------------------------
   # The following steps are run by Jenkins, they should not be run by a human
   # However we need to keep them here because Jenkins expects them to be here
   step "update_docker" "(verify that Jenkins ran) update and submit a PR to Kong's docker-kong repo"
   step "homebrew" "(verify that Jenkins ran) bump version and submit a PR to homebrew-kong"
   step "vagrant" "(verify that Jenkins ran) bump version and submit a PR to kong-vagrant"
   step "pongo" "(verify that Jenkins ran) bump version and submit a PR to kong-pongo"

   exit 0
}


#-------------------------------------------------------------------------------
# Default help
#-------------------------------------------------------------------------------

if [ "$1" = "-h" ] || [ "$1" = "--help" ] || ! [ "$1" ]
then
   version="<x.y.z>"
   usage "$@"
fi

#-------------------------------------------------------------------------------
# Variables
#-------------------------------------------------------------------------------

version="$1"
step="$2"

if ! [[ "$version" =~ ^([0-9]+)\.([0-9]+)\.([0-9])-?((alpha|beta|rc)\.[0-9]+)?$ ]]
then
    die "first argument must be a version in x.y.z format with optional -(alpha|beta|rc).\d suffix"
fi

major=${BASH_REMATCH[1]}
minor=${BASH_REMATCH[2]}
patch=${BASH_REMATCH[3]}
prerelease=${BASH_REMATCH[4]}
rest=${version#*.}
rockspec="kong-$major.$minor.$patch$prerelease-0.rockspec"
branch="release/$version"
base="release/$major.$minor.x"


if [ "$step" = "" ]
then
   usage "$@"
fi

EDITOR="${EDITOR-$VISUAL}"

case "$step" in
   check_dependencies) check_dependencies ;;

   check_milestone) check_milestone ;;

   #---------------------------------------------------------------------------
   create)
      if [ $(git status --untracked-files=no --porcelain | wc -l) != 0 ]
      then
         die "Local tree is not clean, please commit or stash before running this."
      fi

      set -e
      if ! git rev-parse --verify --quiet origin/$base
      then
        git branch "$base"
        git checkout "$base"
        git push -u origin "$base"
      else
        git checkout "$base"
      fi

      git pull
      git checkout -B "$branch"

      SUCCESS "Release branch was created locally." \
              "Ensure to cherry-pick all required changes into $branch." \
      ;;
   #---------------------------------------------------------------------------
   write_changelog) write_changelog "$version" ;;
   commit_changelog) commit_changelog "$version" ;;
   update_copyright) update_copyright "$version" ;;
   update_admin_api_def) update_admin_api_def "$version" ;;

   #---------------------------------------------------------------------------
   version_bump)
      sed -i.bak 's/major = [0-9]*/major = '$major'/' kong/meta.lua
      sed -i.bak 's/minor = [0-9]*/minor = '$minor'/' kong/meta.lua
      sed -i.bak 's/patch = [0-9]*/patch = '$patch'/' kong/meta.lua
      if [ "$prerelease" != "" ]
      then
          sed -i.bak 's/--.*suffix.*$/suffix = "'$prerelease'"/' kong/meta.lua
      fi
      git add kong/meta.lua

      if ! [ -f "$rockspec" ]
      then
         git mv kong-*-0.rockspec "$rockspec"
         sed -i.bak 's/^version = ".*"/version = "'"$major.$minor.$patch$prerelease"'-0"/' "$rockspec"
         sed -i.bak 's/^  tag = ".*"/  tag = "'"$version"'"/' "$rockspec"
      fi

      git status
      git diff

      CONFIRM "If everything looks all right, press Enter to make the release commit" \
              "or Ctrl-C to cancel."

      git add "$rockspec"

      git commit --allow-empty -m "release: $version"
      git log -n 1

      SUCCESS "Version bump for the release is now committed locally." \
              "You are ready to run the next step:" \
              "    $0 $version submit_release_pr"
      ;;

   #---------------------------------------------------------------------------
   submit_release_pr) submit_release_pr "$base" "$branch" "$version" "$prerelease" ;;

   #---------------------------------------------------------------------------
   merge)
      CONFIRM "Press Enter to merge the PR into $base and push the tag and Github release" \
              "or Ctrl-C to cancel."

      set -e
      git checkout "$base"
      git pull
      git merge "$branch"
      git push
      git tag -s "$version" -m "$version"
      git push origin "$version"
      git branch -d "$branch"
      git fetch --prune
      if git rev-parse --verify -q "origin/$branch" > /dev/null
      then
          git push origin :"$branch"
      fi

      make_github_release_file

      if [ "$prerelease" != "" ]
      then
          prerelease_option=--prerelease
      fi

      hub release create $prerelease_option -F "release-$version.txt" "$version"
      rm -f "release-$version.txt"

      SUCCESS "Make sure the packages are built and available on download.konghq.com" \
              "before continuing to the following steps." \

              "They should be visible on https://internal.builds.konghq.com/job/kong/view/tags/. " \
              "An recurrent task checks for new releases every 15 minutes on the server. " \
              "If needed, the link 'Scan Multibranch Pipeline Now' will scan on-demmand. It can be used " \
              "to attempt to rebuild, if there was an error."

              "As the packages are built, you may run the following steps in parallel:" \
              "* 'upload_luarock'" \
              "* 'merge_homebrew'" \
              "* 'merge_vagrant'" \
              "* 'merge_pongo'" \
              "* 'approve_docker', then 'merge_docker', then 'submit_docker'"
      ;;
   #---------------------------------------------------------------------------
   docs_pr) docs_pr "$branch" ;;
   approve_docker) approve_docker ;;
   merge_docker) merge_docker "$branch" "$version" ;;
   submit_docker) submit_docker "$version";;
   merge_homebrew) merge_homebrew ;;
   merge_pongo) merge_pongo ;;
   merge_vagrant) merge_vagrant ;;
   upload_luarock) upload_luarock "$rockspec" "$3" ;;
   announce) announce "$major" "$minor" "$patch" ;;

   # JENKINS-ONLY STEPS: -----------------------------------------------------

   update_docker)
     update_docker "$version"

     SUCCESS "Make sure you get the PR above approved and merged" \
             "before continuing to the step 'merge_docker'."
     ;;

   homebrew)
     if [ -d ../homebrew-kong ]
     then
       cd ../homebrew-kong
     else
       cd ..
       git clone git@github.com:$GITHUB_ORG/homebrew-kong.git
       cd homebrew-kong
     fi

     git checkout master
     git pull
     git checkout -B "$branch"
     bump_homebrew

     git diff

     CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:$GITHUB_ORG/homebrew-kong" \
       "or Ctrl-C to cancel."

     set -e
     git add Formula/kong.rb
     git commit -m "chore(kong): bump kong to $version"

     git push --set-upstream origin "$branch"
     hub pull-request -b master -h "$branch" -m "Release: $version"

     SUCCESS "Make sure you get the PR above approved and merged."
     ;;

    pongo)
      if [ -d ../kong-pongo ]
      then
         cd ../kong-pongo
      else
         cd ..
         git clone git@github.com:$GITHUB_ORG/kong-pongo.git
         cd kong-pongo
      fi

      git checkout master
      git pull
      ./assets/add_version.sh CE "$version"
      if [[ ! $? -eq 0 ]]; then
         exit 1
      fi
      SUCCESS "Make sure you get the PR above approved and merged."
      ;;

    vagrant)
      if [ -d ../kong-vagrant ]
      then
         cd ../kong-vagrant
      else
         cd ..
         git clone git@github.com:$GITHUB_ORG/kong-vagrant.git
         cd kong-vagrant
      fi

      git checkout master
      git pull
      git checkout -B "$branch"
      bump_vagrant

      git diff

      CONFIRM "If everything looks all right, press Enter to commit and send a PR to git@github.com:$GITHUB_ORG/kong-vagrant" \
              "or Ctrl-C to cancel."

      set -e
      git add README.md Vagrantfile
      git commit -m "chore(*): bump Kong to $version"

      git push --set-upstream origin "$branch"
      hub pull-request -b master -h "$branch" -m "Release: $version"

      SUCCESS "Make sure you get the PR above approved and merged."
      ;;

   *)
      die "Unknown step!"
      ;;
esac
