#!/bin/sh
set -eu

usage() {
  printf 'Usage: mqttable-web setup\n' >&2
  printf '       mqttable-web tls-status\n' >&2
  printf 'Run this on the host where your private Web instance is running.\n' >&2
}

case "${1:-}" in
  setup|tls-status)
    if [ "$#" -ne 1 ]; then
      usage
      exit 2
    fi
    ;;
  help|--help|-h)
    usage
    exit 0
    ;;
  *)
    usage
    exit 2
    ;;
esac

bin_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)

if [ -x "$bin_dir/mqttable" ]; then
  release_bin="$bin_dir/mqttable"
elif [ -x "$bin_dir/mqttable_fly" ]; then
  release_bin="$bin_dir/mqttable_fly"
else
  printf 'Mqttable Web release was not found beside this command.\n' >&2
  exit 1
fi

if [ "$1" = tls-status ]; then
  expression='IO.puts("MQTTABLE_TLS_STATUS=" <> Jason.encode!(Mqttable.PrivateWeb.CertificateStatus.public_status()))'
else
  expression='case Mqttable.PrivateWeb.InstanceAccess.issue_setup_secret() do {:ok, secret} -> IO.puts("MQTTABLE_SETUP_SECRET=" <> secret); {:error, reason} -> IO.puts("MQTTABLE_SETUP_ERROR=" <> Atom.to_string(reason)) end'
fi

if ! response=$("$release_bin" rpc "$expression" 2>&1); then
  printf 'Could not contact the running Mqttable instance. Start it and try again.\n' >&2
  exit 1
fi

if [ "$1" = tls-status ]; then
  status=$(printf '%s\n' "$response" | sed -n 's/^MQTTABLE_TLS_STATUS=//p' | tail -n 1)
  if [ -z "$status" ]; then
    printf 'Could not read TLS status from the Mqttable instance.\n' >&2
    exit 1
  fi

  printf '%s\n' "$status"
  case "$status" in
    *'"certificate_state":"ready"'*) exit 0 ;;
    *) exit 1 ;;
  esac
fi

secret=$(printf '%s\n' "$response" | sed -n 's/^MQTTABLE_SETUP_SECRET=//p' | tail -n 1)
error=$(printf '%s\n' "$response" | sed -n 's/^MQTTABLE_SETUP_ERROR=//p' | tail -n 1)

if [ -n "$secret" ]; then
  printf 'Setup code (valid for 15 minutes):\n%s\n\n' "$secret"
  printf 'Open your instance /instance page and enter this code.\n'
  printf 'Issuing another code immediately invalidates this one.\n'
  exit 0
fi

case "$error" in
  already_bound)
    printf 'This instance already has an owner. Sign in from the browser instead.\n' >&2
    ;;
  state_locked)
    printf 'Instance state is locked. Use the server-side recovery procedure.\n' >&2
    ;;
  *)
    printf 'Could not issue a setup code. Check the instance data volume and try again.\n' >&2
    ;;
esac
exit 1
