#!/bin/sh
# xScaler agent installer — served from https://get.xscalerlabs.com/install.sh
#
# Installs the OpenTelemetry OpAMP supervisor managing a contrib collector,
# the same agent shape as deploy/agents/. Only the supervisor connection
# config is written on the host; the collector's own config is never created
# locally — agent-api pushes the assigned template over OpAMP based on the
# agent's labels.
#
# Usage:
#   curl -fsSL https://get.xscalerlabs.com/install.sh | sh -s -- \
#     --token <enrollment-token> [--name <agent-name>] [--collect metrics,logs,traces] \
#     [--platform linux|docker] [--endpoint <opamp-ws-url>] [--image <supervisor-image>]
set -eu

# Pinned to deploy/agents/Dockerfile's OTEL_VERSION.
OTEL_VERSION="0.131.0"
RELEASES="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download"
SUPERVISOR_IMAGE="xscaler/agent-supervisor:local"
ENDPOINT="wss://agents.xscalerlabs.com/v1/opamp"
TOKEN=""
NAME=""
COLLECT=""
PLATFORM=""

usage() {
  sed -n '2,13p' "$0" 2>/dev/null || true
  cat >&2 <<'USAGE'
Flags:
  --token     enrollment token minted in the portal (required)
  --name      agent name label (default: otel-agent-<hostname>)
  --collect   comma-separated signals stamped as a label, e.g. metrics,logs
  --platform  linux | docker (default: auto-detect)
  --endpoint  OpAMP websocket URL (default: wss://agents.xscalerlabs.com/v1/opamp)
  --image     supervisor container image, docker platform only
USAGE
}

fail() { echo "install.sh: $*" >&2; exit 1; }

while [ $# -gt 0 ]; do
  case "$1" in
    --token)    TOKEN="$2"; shift 2 ;;
    --name)     NAME="$2"; shift 2 ;;
    --collect)  COLLECT="$2"; shift 2 ;;
    --platform) PLATFORM="$2"; shift 2 ;;
    --endpoint) ENDPOINT="$2"; shift 2 ;;
    --image)    SUPERVISOR_IMAGE="$2"; shift 2 ;;
    -h|--help)  usage; exit 0 ;;
    *) usage; fail "unknown flag: $1" ;;
  esac
done

[ -n "$TOKEN" ] || { usage; fail "--token is required"; }
[ -n "$NAME" ] || NAME="otel-agent-$(hostname -s 2>/dev/null || echo host)"

if [ -z "$PLATFORM" ]; then
  if [ "$(uname -s)" = "Linux" ] && command -v systemctl >/dev/null 2>&1; then
    PLATFORM=linux
  elif command -v docker >/dev/null 2>&1; then
    PLATFORM=docker
  else
    fail "cannot auto-detect platform; pass --platform linux|docker"
  fi
fi

SUDO=""
if [ "$PLATFORM" = "linux" ] && [ "$(id -u)" != "0" ]; then
  command -v sudo >/dev/null 2>&1 || fail "run as root or install sudo"
  SUDO="sudo"
fi

# $1 = collector executable path, $2 = supervisor storage directory.
supervisor_yaml() {
  cat <<YAML
server:
  endpoint: ${ENDPOINT}
  headers:
    Authorization: "Bearer ${TOKEN}"

capabilities:
  accepts_remote_config: true
  reports_effective_config: true
  reports_remote_config: true
  reports_health: true

agent:
  executable: $1
  description:
    identifying_attributes:
      service.name: io.opentelemetry.collector
    non_identifying_attributes:
      agent_name: ${NAME}${COLLECT:+
      collect: ${COLLECT}}

storage:
  directory: $2
YAML
}

install_linux() {
  arch=$(uname -m)
  case "$arch" in
    x86_64) arch=amd64 ;;
    aarch64|arm64) arch=arm64 ;;
    *) fail "unsupported architecture: $arch" ;;
  esac

  echo "Installing otelcol-contrib ${OTEL_VERSION}..."
  if command -v dpkg >/dev/null 2>&1; then
    curl -fsSL -o /tmp/otelcol-contrib.pkg \
      "${RELEASES}/v${OTEL_VERSION}/otelcol-contrib_${OTEL_VERSION}_linux_${arch}.deb"
    $SUDO dpkg -i /tmp/otelcol-contrib.pkg
  elif command -v rpm >/dev/null 2>&1; then
    curl -fsSL -o /tmp/otelcol-contrib.pkg \
      "${RELEASES}/v${OTEL_VERSION}/otelcol-contrib_${OTEL_VERSION}_linux_${arch}.rpm"
    $SUDO rpm -U /tmp/otelcol-contrib.pkg
  else
    fail "need dpkg or rpm to install the collector"
  fi
  rm -f /tmp/otelcol-contrib.pkg
  # The supervisor spawns the collector itself; the package's own service
  # would fight it over the default config.
  $SUDO systemctl disable --now otelcol-contrib 2>/dev/null || true

  echo "Installing opampsupervisor ${OTEL_VERSION}..."
  curl -fsSL "${RELEASES}/cmd%2Fopampsupervisor%2Fv${OTEL_VERSION}/opampsupervisor_${OTEL_VERSION}_linux_${arch}.tar.gz" \
    | $SUDO tar -xz -C /usr/local/bin opampsupervisor

  collector_bin=$(command -v otelcol-contrib || echo /usr/bin/otelcol-contrib)
  $SUDO mkdir -p /etc/opampsupervisor /var/lib/opampsupervisor
  supervisor_yaml "$collector_bin" /var/lib/opampsupervisor \
    | $SUDO tee /etc/opampsupervisor/supervisor.yaml >/dev/null
  $SUDO chmod 600 /etc/opampsupervisor/supervisor.yaml

  $SUDO tee /etc/systemd/system/opampsupervisor.service >/dev/null <<'UNIT'
[Unit]
Description=OpenTelemetry OpAMP supervisor (xScaler agent)
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/opampsupervisor --config /etc/opampsupervisor/supervisor.yaml
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
UNIT
  $SUDO systemctl daemon-reload
  $SUDO systemctl enable --now opampsupervisor

  echo "Agent '${NAME}' is running (systemd unit: opampsupervisor)."
}

install_docker() {
  command -v docker >/dev/null 2>&1 || fail "docker not found"
  dir=$(mktemp -d)
  # Paths inside the supervisor image (see deploy/agents/Dockerfile).
  supervisor_yaml /usr/local/bin/otelcol-contrib /tmp/supervisor >"$dir/supervisor.yaml"
  docker run -d --name "$NAME" \
    --restart unless-stopped \
    -v "$dir/supervisor.yaml:/etc/supervisor/supervisor.yaml:ro" \
    "$SUPERVISOR_IMAGE" --config /etc/supervisor/supervisor.yaml

  echo "Agent '${NAME}' is running (docker container: ${NAME})."
}

case "$PLATFORM" in
  linux) install_linux ;;
  docker) install_docker ;;
  *) fail "unknown platform: $PLATFORM (want linux|docker)" ;;
esac

echo "It will appear in the portal fleet once it checks in."
