#!/bin/sh
set -eu

CONTROL_PLANE_URL="${NEXA_CONTROL_PLANE_URL:-https://cloud.nexastudio.dev}"
DOWNLOAD_URL="$CONTROL_PLANE_URL/downloads/nexa-agent-linux-amd64"
AGENT_SHA256="a83c40e9aa08393732f9b9bd97033d884856aaa7fca3ea3895959acb928942f3"
STATE_DIR="/var/lib/nexacloud"
STATE_PATH="$STATE_DIR/agent.json"
ENV_DIR="/etc/nexacloud"
ENV_FILE="$ENV_DIR/agent.env"
SERVICE_FILE="/etc/systemd/system/nexa-agent.service"
NODE_NAME="${1:-${NEXA_NODE_NAME:-$(hostname)}}"
TEMP_FILE=""

info() { printf '\n[NexaCloud] %s\n' "$1"; }
fail() { printf '\n[NexaCloud] ERROR: %s\n' "$1" >&2; exit "${2:-1}"; }
cleanup() { [ -z "$TEMP_FILE" ] || rm -f "$TEMP_FILE"; }
trap cleanup EXIT HUP INT TERM

case "$NODE_NAME" in
  *[!A-Za-z0-9._-]*|'') fail "The node name may only contain letters, numbers, dots, underscores and hyphens." 2 ;;
esac

[ "$(id -u)" -eq 0 ] || fail "Run this installer as root (or pipe it to sudo sh)."
[ -r /etc/os-release ] || fail "A supported Debian or Ubuntu system is required."
. /etc/os-release
case "${ID:-}:${ID_LIKE:-}" in
  debian:*|ubuntu:*|*:debian*) ;;
  *) fail "Unsupported operating system: ${PRETTY_NAME:-unknown}. Use Debian 12+ or Ubuntu 22.04+." 3 ;;
esac
command -v apt-get >/dev/null 2>&1 || fail "apt-get is required."
command -v systemctl >/dev/null 2>&1 || fail "systemd is required."

case "$(uname -m)" in
  x86_64|amd64) ;;
  *) fail "Unsupported architecture: $(uname -m). NexaAgent currently requires x86_64." 3 ;;
esac

export DEBIAN_FRONTEND=noninteractive
info "Installing required system packages"
apt-get update -qq
apt-get install -y -qq --no-install-recommends ca-certificates curl
if ! command -v docker >/dev/null 2>&1; then
  apt-get install -y -qq --no-install-recommends docker.io
fi

info "Starting Docker"
systemctl enable --now docker
docker info >/dev/null 2>&1 || fail "Docker was installed but its daemon is not reachable."

info "Checking the NexaCloud control plane"
curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 \
  --connect-timeout 10 --max-time 30 "$CONTROL_PLANE_URL/healthz" >/dev/null || \
  fail "Cannot reach $CONTROL_PLANE_URL. Check DNS, TLS and outbound HTTPS access."

info "Downloading and verifying NexaAgent"
TEMP_FILE="$(mktemp /tmp/nexa-agent.XXXXXX)"
curl --fail --silent --show-error --location --proto '=https' --tlsv1.2 \
  --connect-timeout 10 --max-time 120 "$DOWNLOAD_URL" --output "$TEMP_FILE"
printf '%s  %s\n' "$AGENT_SHA256" "$TEMP_FILE" | sha256sum -c - >/dev/null || \
  fail "NexaAgent checksum verification failed. The existing installation was not changed."
install -m 0755 "$TEMP_FILE" /usr/local/bin/nexa-agent
rm -f "$TEMP_FILE"
TEMP_FILE=""

install -d -m 0700 "$STATE_DIR" "$ENV_DIR"
cat >"$ENV_FILE" <<EOF
NEXA_CONTROL_PLANE_URL=$CONTROL_PLANE_URL
NEXA_NODE_NAME=$NODE_NAME
NEXA_STATE_PATH=$STATE_PATH
EOF
chmod 0600 "$ENV_FILE"

cat >"$SERVICE_FILE" <<EOF
[Unit]
Description=NexaCloud node agent
After=docker.service network-online.target
Wants=network-online.target
Requires=docker.service

[Service]
Type=simple
EnvironmentFile=$ENV_FILE
ExecStart=/usr/local/bin/nexa-agent run
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload

if [ ! -s "$STATE_PATH" ]; then
  info "NexaAgent is installed. Generating a one-time activation code"
  if ! NEXA_CONTROL_PLANE_URL="$CONTROL_PLANE_URL" NEXA_NODE_NAME="$NODE_NAME" NEXA_STATE_PATH="$STATE_PATH" \
    /usr/local/bin/nexa-agent register; then
    fail "Activation was not completed. Run the same install command again to generate a new code." 4
  fi
else
  info "Existing NexaCloud activation found; keeping this node identity"
fi

info "Starting NexaAgent"
systemctl enable nexa-agent
systemctl restart nexa-agent
sleep 2
systemctl is-active --quiet nexa-agent || {
  systemctl --no-pager --full status nexa-agent >&2 || true
  fail "NexaAgent did not start. Review: journalctl -u nexa-agent -n 100"
}

info "Installation complete"
printf 'Node: %s\nService: active\nDashboard: %s/dashboard/infrastructure\n' "$NODE_NAME" "$CONTROL_PLANE_URL"
