#!/usr/bin/env bash

__gce_sd_here="$(dirname "${BASH_SOURCE[0]}")"
# shellcheck disable=SC1091
__gce_sd_conf="${__gce_sd_here}/gce-self-destruct.conf"

gce_metadata_req() {
  declare endpoint url
  endpoint="$1"
  url="http://metadata.google.internal/computeMetadata/v1/$endpoint"
  curl -sf -H Metadata-Flavor:Google "$url"
}

unix_to_at_time() {
  declare unix="$1"
  date --date="@$unix" "+%Y%m%d%H%M.%S"
}

timeout_to_destruct() {
  declare timeout_sec now_unix
  declare timeout_hrs=$1
  timeout_sec=$((timeout_hrs * 60 * 60))
  now_unix=$(date +%s)
  echo $((now_unix + timeout_sec))
}

relative_timespan()
{
  declare timeSpan="$1"
  declare -a units divs
  units+=( s ); divs+=( 60 )
  units+=( m ); divs+=( 60 )
  units+=( h ); divs+=( 24 )
  units+=( d ); divs+=( 7 )
  units+=( w ); divs+=( 52 )
  numUnits="${#units[@]}"
  units+=( y ); divs+=( 100 )

  declare -a outs
  declare i div remain
  for (( i=0; i < "$numUnits"; i++ )); do
    div="${divs[$i]}"
    [[ "$timeSpan" -lt "$div" ]] && break
    remain="$((timeSpan % div))"
    timeSpan="$((timeSpan / div))"
    outs+=( "$remain" )
  done
  outs+=( "$timeSpan" )

  numOut="${#outs[@]}"
  out1="$((numOut-1))"
  out2="$((numOut-2))"

  if [[ "$numOut" -eq 1 ]] || \
    [[ "$numOut" -ge "$numUnits" && \
      "${outs[out1]}" -ge "${divs[out1]}" ]]; then
    printf "%d%s" "${outs[out1]}" "${units[out1]}"
  else
    printf "%d%s%02d%s" "${outs[out1]}" \
      "${units[out1]}" "${outs[out2]}" "${units[out2]}"
  fi
}

gce_self_destruct_ttl() {
  declare colorize="${1:-true}"
  declare prefix="${2}"
  declare suffix="${3}"
  declare output=0

  if [[ -f "${__gce_sd_conf}" ]]; then
    # shellcheck disable=SC1090
    source "${__gce_sd_conf}"
    declare ttl pttl color
    ttl="$((destruct - $(date +%s)))"
    if [[ "$ttl" -lt 0 ]]; then
      ttl=0
    fi
    pttl="$(relative_timespan "$ttl")"
    color=
    if [[ ttl -lt 3600 ]]; then
      color="\033[01;31m"
    fi
    output="${prefix}${pttl}${suffix}"
    if $colorize; then
      output="${color}${output}\033[01;00m"
    fi
  fi
  echo -e "$output"
}

gce_self_destruct_setup() {
  declare destruct at_time zone
  destruct="$(timeout_to_destruct "$1")"
  at_time="$(unix_to_at_time "$destruct")"
  zone=$(gce_metadata_req "instance/zone")
  zone=$(basename "$zone")

  cat >"${__gce_sd_conf}" <<EOF
export destruct=$destruct
export zone=$zone
EOF

  at -t "$at_time" <<EOF
bash -i <<'EOF2'
source /solana-scratch/gce-self-destruct.sh
gce_self_destruct_check
EOF2
EOF
}

gce_self_destruct_check() {
  if [[ -f "${__gce_sd_conf}" ]]; then
    # shellcheck disable=SC1090
    source "${__gce_sd_conf}"
    declare now gcloudBin
    now=$(date +%s)
    if [[ "$now" -ge "$destruct" ]]; then
      # gcloud is installed in /snap/bin, but /snap/bin isn't in root's PATH...
      gcloudBin="$(command -v gcloud)"
      gcloudBin="${gcloudBin:-/snap/bin/gcloud}"
      "$gcloudBin" compute instances delete --quiet "$(hostname)" --zone "$zone"
    else
      at -t "$(unix_to_at_time "$destruct")" <<EOF
bash -i <<'OEF2'
source /solana-scratch/gce-self-destruct.sh
gce_self_destruct_check
EOF2
EOF
    fi
  fi
}

gce_self_destruct_motd() {
  declare ttl
  ttl="$(gce_self_destruct_ttl)"
  echo -e '\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n'
  if [[ -n "${ttl}" ]]; then
    echo -e "\tThis instance will self-destruct in ${ttl}!"
  else
    echo -e "\tThis instance will NOT self-destruct. YOU are responsible for deleting it!"
  fi
  echo -e '\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n'
}

gce_self_destruct_ps1() {
  declare ttl
  ttl="$(gce_self_destruct_ttl true "[T-" "]")"
  ttl="${ttl:-"[T-~~~~~]"}"
  echo "!${ttl}"
}