#!/bin/sh
# Installs the Solo Enterprise for agentgateway binaries from the release bucket.
# Published to the bucket root as install.sh; run it with:
#
#   curl -fsSL https://storage.googleapis.com/enterprise-agentgateway-standalone/install.sh | sh
#
# Environment:
#   AGENTGATEWAY_VERSION      version to install (default: newest stable release)
#   AGENTGATEWAY_INSTALL_DIR  where to put the binaries (default: $HOME/.agentgateway/bin)
#   GCS_BUCKET                release bucket to install from (default: enterprise-agentgateway-standalone)

set -eu

DEFAULT_BUCKET="enterprise-agentgateway-standalone"

VERSION="${AGENTGATEWAY_VERSION:-}"
GCS_BUCKET="${GCS_BUCKET:-$DEFAULT_BUCKET}"
INSTALL_DIR="${AGENTGATEWAY_INSTALL_DIR:-$HOME/.agentgateway/bin}"
BASE_URL="https://storage.googleapis.com/${GCS_BUCKET}"

# releases.txt holds the stable releases in this bucket, newest first; prereleases are
# left out of it and have to be asked for by version.
if [ -z "${VERSION}" ] || [ "${VERSION}" = "latest" ]; then
  if ! VERSION="$(curl -fsSL "${BASE_URL}/releases.txt" | head -n 1)" || [ -z "${VERSION}" ]; then
    echo "Error: could not determine the latest version from ${BASE_URL}/releases.txt" >&2
    echo "If this persists, please contact support." >&2
    exit 1
  fi
fi

case "$(uname -s | tr '[:upper:]' '[:lower:]')" in
  linux)  OS=linux ;;
  darwin) OS=darwin ;;
  *)
    echo "Error: no build is published for $(uname -s)." >&2
    echo "Linux and macOS are installable here; on Windows download" >&2
    echo "agentgateway-enterprise-windows-amd64.exe and agentgateway-enterprise-sts-windows-amd64.exe directly." >&2
    exit 1
    ;;
esac

case "$(uname -m)" in
  aarch64|arm64) ARCH=arm64 ;;
  x86_64|amd64)  ARCH=amd64 ;;
  *) echo "Error: unsupported architecture $(uname -m)." >&2; exit 1 ;;
esac

if [ "$OS" = "darwin" ] && [ "$ARCH" != "arm64" ]; then
  echo "Error: macOS builds are published for arm64 only." >&2
  exit 1
fi

# Resolved at top level: `exit 1` inside a command substitution would only blank the
# checksum and report a mismatch.
if command -v sha256sum >/dev/null 2>&1; then
  checksum_of() { sha256sum "$1" | cut -d' ' -f1; }
elif command -v shasum >/dev/null 2>&1; then
  checksum_of() { shasum -a 256 "$1" | cut -d' ' -f1; }
elif command -v openssl >/dev/null 2>&1; then
  checksum_of() { openssl dgst -sha256 "$1" | awk '{ print $NF }'; }
else
  echo "Error: need one of sha256sum, shasum, or openssl to validate the download." >&2
  exit 1
fi

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

# published artifact name -> name to install it as
COMPONENTS="agentgateway-enterprise:agentgateway agentgateway-enterprise-sts:agentgateway-sts"

echo "Installing Solo Enterprise for agentgateway ${VERSION} (${OS}-${ARCH})..."

for component in ${COMPONENTS}; do
  artifact="${component%%:*}-${OS}-${ARCH}"
  installed="${component#*:}"
  url="${BASE_URL}/${VERSION}/${artifact}"

  echo "  downloading ${artifact}"
  if ! curl -fsSL "${url}" -o "${tmp}/${artifact}"; then
    echo "Error: ${url} could not be downloaded." >&2
    echo "Check that ${VERSION} exists in ${BASE_URL}/releases.txt." >&2
    exit 1
  fi

  # Separate from the cut below, whose status would mask a 404 as a mismatch.
  if ! sha_line="$(curl -fsSL "${url}.sha256")" || [ -z "${sha_line}" ]; then
    echo "Error: ${url}.sha256 could not be downloaded, so ${artifact} cannot be verified." >&2
    exit 1
  fi
  expected="$(echo "${sha_line}" | cut -d' ' -f1)"
  actual="$(checksum_of "${tmp}/${artifact}")"
  if [ "${expected}" != "${actual}" ]; then
    echo "Error: checksum mismatch for ${artifact} (expected ${expected}, got ${actual})." >&2
    exit 1
  fi

  chmod +x "${tmp}/${artifact}"
  mv "${tmp}/${artifact}" "${tmp}/${installed}"
done

# Only after every download verified, so a failure leaves any existing install alone.
mkdir -p "${INSTALL_DIR}"
mv "${tmp}"/* "${INSTALL_DIR}/"

if ! "${INSTALL_DIR}/agentgateway" --version >/dev/null 2>&1; then
  echo "Error: the downloaded agentgateway binary does not run on this system." >&2
  exit 1
fi

cat <<EOF

Installed ${VERSION} to ${INSTALL_DIR}:
  agentgateway      the proxy
  agentgateway-sts  the STS server

Add them to your PATH with:
  export PATH=${INSTALL_DIR}:\$PATH
EOF
