#!/usr/bin/env sh
set -eu

DEFAULT_DOWNLOAD_BASE='https://relay.cre8.xyz/releases'
DEFAULT_VERSION='latest'

usage() {
  cat <<'USAGE'
Install the CRE8 runtime peer bundle.

Usage:
  install.sh [latest|stable|VERSION] [--service]

Environment:
  CRE8_DOWNLOAD_BASE   Override bundle base URL.
  CRE8_VERSION         Override default version/channel.
  CRE8_INSTALL_DIR     Install root. Default: $HOME/.local/share/cre8
  CRE8_BIN_DIR         Symlink directory. Default: $HOME/.local/bin
  CRE8_SKIP_CHECKSUM   Set to 1 to allow unsigned local test bundles.
USAGE
}

VERSION="${CRE8_VERSION:-$DEFAULT_VERSION}"
INSTALL_SERVICE=0

while [ "$#" -gt 0 ]; do
  case "$1" in
    -h|--help)
      usage
      exit 0
      ;;
    --service)
      INSTALL_SERVICE=1
      ;;
    latest|stable|v[0-9]*|[0-9]*)
      VERSION="$1"
      ;;
    *)
      echo "cre8 install: unknown argument: $1" >&2
      usage >&2
      exit 2
      ;;
  esac
  shift
done

DOWNLOAD_BASE="${CRE8_DOWNLOAD_BASE:-$DEFAULT_DOWNLOAD_BASE}"
INSTALL_DIR="${CRE8_INSTALL_DIR:-$HOME/.local/share/cre8}"
BIN_DIR="${CRE8_BIN_DIR:-$HOME/.local/bin}"

detect_platform() {
  os="$(uname -s | tr '[:upper:]' '[:lower:]')"
  arch="$(uname -m)"
  case "$os:$arch" in
    linux:x86_64|linux:amd64) echo "linux-x64" ;;
    linux:aarch64|linux:arm64) echo "linux-arm64" ;;
    darwin:x86_64|darwin:amd64) echo "darwin-x64" ;;
    darwin:aarch64|darwin:arm64) echo "darwin-arm64" ;;
    *)
      echo "cre8 install: unsupported platform $os/$arch" >&2
      exit 1
      ;;
  esac
}

fetch() {
  url="$1"
  out="$2"
  if command -v curl >/dev/null 2>&1; then
    curl -fL --retry 3 --connect-timeout 15 -o "$out" "$url"
  elif command -v wget >/dev/null 2>&1; then
    wget -O "$out" "$url"
  else
    echo "cre8 install: curl or wget is required" >&2
    exit 1
  fi
}

verify_checksum() {
  archive="$1"
  artifact="$2"
  sums="$3"

  if [ "${CRE8_SKIP_CHECKSUM:-}" = "1" ]; then
    echo "cre8 install: skipping checksum because CRE8_SKIP_CHECKSUM=1" >&2
    return 0
  fi

  if command -v sha256sum >/dev/null 2>&1; then
    CHECKSUM_TOOL=sha256sum
  elif command -v shasum >/dev/null 2>&1; then
    CHECKSUM_TOOL=shasum
  else
    echo "cre8 install: sha256sum or shasum is required for checksum verification" >&2
    echo "cre8 install: set CRE8_SKIP_CHECKSUM=1 only for local unsigned test bundles" >&2
    exit 1
  fi

  if ! grep -F "  $artifact" "$sums" > "$sums.one"; then
    echo "cre8 install: checksum entry missing for $artifact" >&2
    exit 1
  fi

  cp "$archive" "$(dirname "$archive")/$artifact"
  if [ "$CHECKSUM_TOOL" = "sha256sum" ]; then
    (cd "$(dirname "$archive")" && sha256sum -c "$(basename "$sums.one")")
  else
    (cd "$(dirname "$archive")" && shasum -a 256 -c "$(basename "$sums.one")")
  fi
}

install_user_service() {
  target_bin="$1"
  if [ "$(uname -s)" != "Linux" ] || ! command -v systemctl >/dev/null 2>&1; then
    echo "cre8 install: --service currently needs Linux with systemd user services" >&2
    return 0
  fi

  unit_dir="$HOME/.config/systemd/user"
  unit_file="$unit_dir/cre8-runtime-peer.service"
  mkdir -p "$unit_dir"
  cat > "$unit_file" <<UNIT
[Unit]
Description=CRE8 runtime peer
After=network-online.target

[Service]
ExecStart=$target_bin
Restart=on-failure
Environment=CRE8_GATEWAY_AUTOSTART=true

[Install]
WantedBy=default.target
UNIT

  systemctl --user daemon-reload
  systemctl --user enable --now cre8-runtime-peer.service
  echo "cre8 install: systemd user service started: cre8-runtime-peer.service"
}

PLATFORM="$(detect_platform)"
ARTIFACT="cre8-runtime-peer-$VERSION-$PLATFORM.tar.gz"
ARCHIVE_URL="$DOWNLOAD_BASE/$VERSION/$ARTIFACT"
SUMS_URL="$DOWNLOAD_BASE/$VERSION/SHA256SUMS"
TMP_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t cre8-install)"
cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT INT TERM

ARCHIVE="$TMP_DIR/$ARTIFACT.download"
SUMS="$TMP_DIR/SHA256SUMS"

echo "cre8 install: downloading $ARTIFACT"
fetch "$ARCHIVE_URL" "$ARCHIVE"
fetch "$SUMS_URL" "$SUMS"
verify_checksum "$ARCHIVE" "$ARTIFACT" "$SUMS"

mkdir -p "$INSTALL_DIR/peer" "$BIN_DIR"
tar -xzf "$ARCHIVE" -C "$INSTALL_DIR/peer" --strip-components=1

if [ -x "$INSTALL_DIR/peer/bin/cre8runtime" ]; then
  TARGET_BIN="$INSTALL_DIR/peer/bin/cre8runtime"
elif [ -x "$INSTALL_DIR/peer/bin/cre8_runtime" ]; then
  TARGET_BIN="$INSTALL_DIR/peer/bin/cre8_runtime"
elif [ -x "$INSTALL_DIR/peer/cre8runtime" ]; then
  TARGET_BIN="$INSTALL_DIR/peer/cre8runtime"
else
  echo "cre8 install: bundle did not contain bin/cre8runtime" >&2
  exit 1
fi

ln -sf "$TARGET_BIN" "$BIN_DIR/cre8runtime"

if [ "$INSTALL_SERVICE" = "1" ]; then
  install_user_service "$TARGET_BIN"
fi

echo "cre8 install: installed $TARGET_BIN"
echo "cre8 install: linked $BIN_DIR/cre8runtime"
case ":$PATH:" in
  *":$BIN_DIR:"*) ;;
  *) echo "cre8 install: add $BIN_DIR to PATH to run cre8runtime directly" ;;
esac
echo "cre8 install: start with: CRE8_GATEWAY_AUTOSTART=true $BIN_DIR/cre8runtime"
