#!/bin/bash

# This script checks the region health of your Spanner dual-region instance
# configuration. If the region is healthy, then the script runs the
# `gcloud spanner databases change-quorum` command to manually failover the
# dual-region quorum from dual-region to the healthy single region. Remember to
# manually failback if you perform a manual failover.

# Example:
# ./change_quorum_with_region_health_check.sh \
#   --project=span-cloud-testing \
#   --instance=test-instance \
#   --database=test-database \
#   --serving_location=asia-northeast2

PROJECT=""
INSTANCE=""
DATABASE=""
SERVING_LOCATION=""

for i in "$@"; do
  case $i in
    -p=*|--project=*)
      PROJECT="${i#*=}"
      shift # past argument=value
      ;;
    -i=*|--instance=*)
      INSTANCE="${i#*=}"
      shift # past argument=value
      ;;
    -d=*|--database=*)
      DATABASE="${i#*=}"
      shift # past argument=value
      ;;
    -s=*|--serving_location=*)
      SERVING_LOCATION="${i#*=}"
      shift # past argument=value
      ;;
    -*|--*)
      echo "Unknown option $i"
      exit 1
      ;;
    *)
      ;;
  esac
done

if [[ ! "${PROJECT}" ]]; then
  echo "Input project is required."
  exit 1
fi

if [[ ! "${INSTANCE}" ]]; then
  echo "Input instance is required."
  exit 1
fi

if [[ ! "${DATABASE}" ]]; then
  echo "Input database is required."
  exit 1
fi

if [[ ! "${SERVING_LOCATION}" ]]; then
  echo "Input serving_location is required."
  exit 1
fi

start_time=$(date --date='5 minutes ago' -u +"%FT%TZ")
end_time=$(date -u +"%FT%TZ")

read -r -d '' url <<URL
https://monitoring.googleapis.com/v3/projects/${PROJECT}/timeSeries?
aggregation.alignmentPeriod=300s&aggregation.crossSeriesReducer=REDUCE_FRACTION_TRUE
&aggregation.groupByFields=resource.labels.location
&aggregation.perSeriesAligner=ALIGN_NEXT_OLDER
&filter=metric.labels.quorum_availability=Healthy%20AND%20
metric.type=%22spanner.googleapis.com/instance/dual_region_quorum_availability%22%20AND%20
resource.labels.location=${SERVING_LOCATION}
&interval.endTime=${end_time}
&interval.startTime=${start_time}
URL

# Remove new lines from the url
url=$(echo "${url}" | tr -d '\n')

result=$(curl -X GET -s -H 'Content-Type:application/json' -H 'Accept: application/json' \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "X-Goog-User-Project: ${PROJECT}" "${url}")

if [[ $? -eq 0 ]]; then
  if [[ ${result} =~ "timeSeries" ]]; then
    echo "Region ${SERVING_LOCATION} is healthy."
    gcloud spanner databases change-quorum \
      "${DATABASE}" --instance="${INSTANCE}" \
      --single-region --serving-location="${SERVING_LOCATION}"
  else
    # No time series entry found
    echo "Region ${SERVING_LOCATION} is not healthy. Skip change-quorum operation."
  fi
else
  exit 1
fi
