#!/bin/bash

### Install PR ###
#
# This script takes a Github pull request number as an argument, downloads the
# docker images from the pull request's artifacts, pushes them, and installs
# them on your Kubernetes cluster.  Requires a Github personal access token
# in the $GITHUB_TOKEN environment variable.

set -eo pipefail

# Read script flags and arguments
while :
do
  case $1 in
    -h|--help)
      echo "Install Linkerd with the changes made in a GitHub Pull Request."
      echo ""
      echo "Usage:"
      echo "    --context: The name of the kubeconfig context to use"
      echo ""
      echo "    # Install Linkerd into the current cluster"
      echo "    bin/install-pr 1234"
      echo ""
      echo "    # Install Linkerd into the current KinD cluster"
      echo "    bin/install-pr [-k|--kind] 1234"
      echo ""
      echo "    # Install Linkerd into the 'kind-pr-1234' KinD cluster"
      echo "    bin/install-pr [-k|--kind] --context kind-pr-1234 1234"
      exit 0
      ;;
    --context)
      context=$2
      shift
      ;;
    -k|--kind)
      is_kind=1
      ;;
    -?*)
      echo "Error: Unknown option: $1" >&2
      exit 1
      ;;
    *)
      break
  esac
  shift
done

pr=$1

if [ -z "$pr" ]
then
  echo "Error: ${0##*/} accepts 1 argument" >&2
  echo "Usage:" >&2
  echo "    ${0##*/} ####" >&2
  exit 1
fi

if [ -z "$GITHUB_TOKEN" ]
then
  # shellcheck disable=SC2016
  echo 'Error: Generate a personal access token at https://github.com/settings/tokens and set it in the $GITHUB_TOKEN env var'
  exit 1
fi

linkerd2_pulls_url="https://api.github.com/repos/linkerd/linkerd2/pulls"
linkerd2_kind_integration_url="https://api.github.com/repos/linkerd/linkerd2/actions/workflows/kind_integration.yml"

# Get the URL for downloading the artifacts archive
auth="Authorization: token $GITHUB_TOKEN"
branch=$(curl -sL -H "$auth" "$linkerd2_pulls_url/$pr" | jq -r '.head.ref')
artifacts=$(curl -sL -H "$auth" "$linkerd2_kind_integration_url/runs?branch=$branch" | jq -r '.workflow_runs[0].artifacts_url')
archive=$(curl -sL -H "$auth" "$artifacts" | jq -r '.artifacts[0].archive_download_url')

bindir=$( cd "${BASH_SOURCE[0]%/*}" && pwd )
dir=$(mktemp -d -t "linkerd-pr-$pr.XXXXXXXXXX")

cd "$dir" || exit

echo "### Downloading images ###"

curl -L -o archive.zip -H "$auth" "$archive"
unzip -o archive.zip

echo "### Loading images into Docker ###"

image=$(docker load -i cli-bin.tar | sed 's/Loaded image: //')
tag=$(echo "$image" | cut -f 2 -d ":")

if [ $is_kind ]
then
  # KinD context strings are created by prepending `kind-` to the cluster name
  if [ "$context" ]
  then
    name=$(echo "$context" | sed -n -E "s/(kind)-(.*)/\2/p")
  fi

  "$bindir"/kind-load --images ${name:+'--name' "$name"}
else
  for image in cni-plugin controller debug grafana proxy web
  do
    image=$(docker load -i "$image.tar" | sed 's/Loaded image: //')
    docker push "$image"
  done
fi

cd -

rm -rf "$dir"

case $(uname) in
  Darwin)
    platform="darwin"
    ;;
  Linux)
    platform="linux"
    ;;
  *)
    platform="windows"
    ;;
esac

linkerd=$("$bindir"/docker-pull-binaries "$tag" | awk -v platform=$platform '$0 ~ platform')

echo "### Pre checks ###"

(
  set -x
  "$linkerd" ${context:+'--context' "$context"} check --pre
)

echo "### Installing $tag ###"

(
  set -x
  "$linkerd" ${context:+'--context' "$context"} install | kubectl ${context:+'--context' "$context"} apply -f -
  "$linkerd" ${context:+'--context' "$context"} check
)

echo ""
echo "Linkerd installed. CLI available:"
echo "$linkerd"
