#!/bin/sh

set -eu

repository_url="${DOPBASE_REPOSITORY_URL:-https://github.com/dopbase/dopbase}"
install_dir="${DOPBASE_INSTALL_DIR:-${HOME}/.local/bin}"
umami_url="https://gateway.umami.is/api/send"
umami_website_id="6271ae4c-9b9e-4c60-83a3-a980021b7138"
asset_os="unknown"
asset_arch="unknown"
telemetry_version="unknown"
install_stage="prerequisites"
install_succeeded=0
temporary_dir=""
temporary_target=""

require_command() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "dopbase installer: required command not found: $1" >&2
    exit 1
  fi
}

send_install_event() {
  event_name=$1
  event_stage=$2

  event_payload=$(printf '%s' \
    '{"type":"event","payload":{"website":"'"$umami_website_id"'","hostname":"dopbase.com","url":"/install.sh","name":"'"$event_name"'","data":{"version":"'"$telemetry_version"'","os":"'"$asset_os"'","arch":"'"$asset_arch"'","installer":"shell","stage":"'"$event_stage"'"}}}')

  curl -fsS \
    --connect-timeout 2 \
    --max-time 3 \
    -X POST \
    -H "Content-Type: application/json" \
    -H "x-umami-website-id: ${umami_website_id}" \
    -H "x-umami-hostname: dopbase.com" \
    -H "User-Agent: DopbaseInstaller/${telemetry_version} (shell; ${asset_os} ${asset_arch})" \
    --data "$event_payload" \
    "$umami_url" >/dev/null 2>&1 || true
}

handle_exit() {
  exit_status=$?
  trap - EXIT HUP INT TERM

  if [ "$exit_status" -ne 0 ] && [ "$install_succeeded" -ne 1 ]; then
    send_install_event "install-failure" "$install_stage"
  fi

  if [ -n "$temporary_target" ]; then
    rm -f "$temporary_target" || true
  fi
  if [ -n "$temporary_dir" ]; then
    rm -rf "$temporary_dir" || true
  fi

  exit "$exit_status"
}

require_command curl
trap 'handle_exit' EXIT
trap 'exit 1' HUP INT TERM
require_command unzip

install_stage="platform"
case "$(uname -s)" in
Darwin) asset_os="darwin" ;;
Linux) asset_os="linux" ;;
*)
  echo "dopbase installer: only macOS and Linux are supported" >&2
  exit 1
  ;;
esac

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

install_stage="release"
if [ -n "${DOPBASE_VERSION:-}" ]; then
  release_tag=$DOPBASE_VERSION
else
  latest_url=$(curl -fsSLI -o /dev/null -w '%{url_effective}' "${repository_url}/releases/latest")
  release_tag=${latest_url##*/}
fi

case "$release_tag" in
v[0-9]*.[0-9]*.[0-9]*) version=${release_tag#v} ;;
[0-9]*.[0-9]*.[0-9]*) version=$release_tag ;;
*)
  echo "dopbase installer: invalid release tag: ${release_tag}" >&2
  exit 1
  ;;
esac

if ! printf '%s\n' "$version" | awk -F. '
  NF == 3 && $1 ~ /^[0-9]+$/ && $2 ~ /^[0-9]+$/ && $3 ~ /^[0-9]+$/ { valid = 1 }
  END { exit valid ? 0 : 1 }
'; then
  echo "dopbase installer: invalid version: ${version}" >&2
  exit 1
fi

telemetry_version=$version
archive_name="dopbase_${version}_${asset_os}_${asset_arch}.zip"
release_base_url="${DOPBASE_DOWNLOAD_BASE_URL:-${repository_url}/releases/download/${release_tag}}"
install_stage="download"
temporary_dir=$(mktemp -d "${TMPDIR:-/tmp}/dopbase-install.XXXXXX")

archive_path="${temporary_dir}/${archive_name}"
checksums_path="${temporary_dir}/checksums.txt"

echo "Downloading Dopbase ${version} for ${asset_os}/${asset_arch}..."
curl -fsSL "${release_base_url}/${archive_name}" -o "$archive_path"
curl -fsSL "${release_base_url}/checksums.txt" -o "$checksums_path"

install_stage="checksum"
expected_checksum=$(awk -v archive="$archive_name" '$2 == archive { print $1 }' "$checksums_path")
if [ -z "$expected_checksum" ]; then
  echo "dopbase installer: checksum not found for ${archive_name}" >&2
  exit 1
fi

if command -v sha256sum >/dev/null 2>&1; then
  actual_checksum=$(sha256sum "$archive_path" | awk '{ print $1 }')
elif command -v shasum >/dev/null 2>&1; then
  actual_checksum=$(shasum -a 256 "$archive_path" | awk '{ print $1 }')
else
  echo "dopbase installer: sha256sum or shasum is required" >&2
  exit 1
fi

if [ "$actual_checksum" != "$expected_checksum" ]; then
  echo "dopbase installer: checksum verification failed" >&2
  exit 1
fi

install_stage="extract"
extract_dir="${temporary_dir}/extract"
mkdir -p "$extract_dir"
unzip -q "$archive_path" dopbase -d "$extract_dir"

if [ ! -f "${extract_dir}/dopbase" ]; then
  echo "dopbase installer: release archive does not contain dopbase" >&2
  exit 1
fi

install_stage="install"
mkdir -p "$install_dir"
temporary_target="${install_dir}/.dopbase.install.$$"
cp "${extract_dir}/dopbase" "$temporary_target"
chmod 755 "$temporary_target"
mv -f "$temporary_target" "${install_dir}/dopbase"
temporary_target=""

install_succeeded=1
install_stage="complete"
send_install_event "install-success" "$install_stage"

echo "Installed Dopbase ${version} to ${install_dir}/dopbase"
case ":${PATH}:" in
*":${install_dir}:"*) ;;
*) echo "Add ${install_dir} to PATH before running dopbase." ;;
esac

echo
echo "Quick start:"
echo "  dopbase server start  Run in the foreground"
echo "  dopbase server up     Run in the background"
echo "  dopbase server down   Stop the background server"
echo
echo "Quick start: https://docs.dopbase.com/guide/quick-start"
echo "Server commands: https://docs.dopbase.com/cli/serve"
