#!/bin/bash

# Usage: ./bramble-rmm-install.sh <ENROLLMENT_KEY> [SERVER_URL]
# SERVER_URL is optional — omit it and the agent points at the production
# API host exactly as before. Pass it to enroll a device against a
# different API host instead (e.g. testing the brambleit.cloud vanity-domain
# migration via https://bramble.brambleit.cloud/api before cutting over the
# default for everyone).
# Run as root or with sudo available — works either way (e.g. Proxmox
# hosts are typically root-only, with no sudo binary installed at all).

set -e

ENROLLMENT_KEY="$1"
SERVER_URL_GIVEN=false
[ -n "$2" ] && SERVER_URL_GIVEN=true
SERVER_URL="${2:-https://api.cloud.brambleit.com}"

if [ -z "$ENROLLMENT_KEY" ]; then
  echo "Enrollment key not provided."
  exit 1
fi

if [ "$(id -u)" -eq 0 ]; then
  SUDO=""
  SUDO_E=""
elif command -v sudo &> /dev/null; then
  SUDO="sudo"
  SUDO_E="sudo -E"
else
  echo "This must be run as root, or with sudo installed and available." >&2
  exit 1
fi

INSTALL_DIR="/opt/bramble-rmm"
TEMP_DIR="$INSTALL_DIR/temp"
NODE_MIN_VERSION="22"

echo "Creating directories..."
$SUDO mkdir -p "$TEMP_DIR"
$SUDO mkdir -p "$INSTALL_DIR/temp"
cd "$TEMP_DIR"

# Detect OS and install dependencies
install_dependencies() {
  echo "Installing required packages..."

  if [ -f /etc/debian_version ]; then
    $SUDO apt-get update
    $SUDO apt-get install -y curl jq unzip

    if ! command -v node &> /dev/null || [ "$(node -v | cut -d. -f1 | tr -d v)" -lt "$NODE_MIN_VERSION" ]; then
      curl -fsSL https://deb.nodesource.com/setup_22.x | $SUDO_E bash -
      $SUDO apt-get install -y nodejs
    fi

  elif [ -f /etc/redhat-release ]; then
    $SUDO dnf install -y curl jq unzip

    if ! command -v node &> /dev/null || [ "$(node -v | cut -d. -f1 | tr -d v)" -lt "$NODE_MIN_VERSION" ]; then
      curl -fsSL https://rpm.nodesource.com/setup_22.x | $SUDO bash -
      $SUDO dnf install -y nodejs
    fi

  else
    echo "Unsupported OS. Please install dependencies manually."
    exit 1
  fi
}

install_dependencies

# Ensure Node is now installed
if ! command -v node &> /dev/null || ! command -v npm &> /dev/null; then
  echo "Node.js or npm installation failed. Exiting."
  exit 1
fi

# Download latest agent
echo "Downloading Bramble RMM agent..."
VERSION_INFO=$(curl -fsS "$SERVER_URL/v1/app/rmm/version/agent/linux")
AGENT_VERSION=$(echo "$VERSION_INFO" | jq -r '.latest // empty')
EXPECTED_SHA256=$(echo "$VERSION_INFO" | jq -r '.sha256 // empty')

if [ -z "$AGENT_VERSION" ]; then
  echo "Could not determine latest agent version from the API. Aborting." >&2
  exit 1
fi

if [ -z "$EXPECTED_SHA256" ]; then
  echo "No checksum published for agent v$AGENT_VERSION. Refusing to install without integrity verification." >&2
  exit 1
fi

AGENT_ZIP="Base_Client_v$AGENT_VERSION.zip"
ZIP_PATH="$TEMP_DIR/$AGENT_ZIP"
curl -fsSL -o "$ZIP_PATH" "https://download.cloud.brambleit.com/rmm/agent/linux/$AGENT_ZIP"

echo "Verifying checksum..."
ACTUAL_SHA256=$(sha256sum "$ZIP_PATH" | awk '{print $1}')
if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
  echo "Checksum mismatch for $AGENT_ZIP: expected $EXPECTED_SHA256, got $ACTUAL_SHA256. Aborting install." >&2
  rm -f "$ZIP_PATH"
  exit 1
fi
echo "Checksum verified."

echo "Replacing agent files..."

echo "Extracting new version of Bramble RMM..."
# Extract new version directly into the install dir
$SUDO unzip -o "$TEMP_DIR/$AGENT_ZIP" -d "$INSTALL_DIR"
echo "Moving new version of Bramble RMM..."
$SUDO cp -r "$INSTALL_DIR/build/"* "$INSTALL_DIR/"
echo "Cleaning up build folder..."
$SUDO rm -rf "$INSTALL_DIR/build"

echo "Installing packages..."
cd "$INSTALL_DIR"
npm install

# Make all .sh files executable
echo "Making .sh files executable..."
find "$INSTALL_DIR" -type f -name "*.sh" -exec $SUDO chmod +x {} \;

echo "Setting folder permissions..."
$SUDO chown -R root:root "$INSTALL_DIR"
$SUDO chmod -R 755 "$INSTALL_DIR"

# Ensure config.json is writable if it exists
CONFIG_FILE="$INSTALL_DIR/config.json"

if [ -f "$CONFIG_FILE" ]; then
  echo "Setting permissions on config.json..."
  $SUDO chmod 644 "$CONFIG_FILE"
  if [ "$SERVER_URL_GIVEN" = true ]; then
    echo "Updating RMM_ServerURL on already-enrolled device to $SERVER_URL..."
    UPDATED_CONFIG=$(jq --arg url "$SERVER_URL" '.RMM_ServerURL = $url' "$CONFIG_FILE")
    echo "$UPDATED_CONFIG" | $SUDO tee "$CONFIG_FILE" > /dev/null
  fi
else
  echo "Creating config.json..."
  $SUDO tee "$CONFIG_FILE" > /dev/null <<EOF
{
  "RMM_Enrolled": false,
  "RMM_ServerURL": "$SERVER_URL",
  "RMM_EnrollmentKey": "$ENROLLMENT_KEY"
}
EOF
  $SUDO chmod 644 "$CONFIG_FILE"
fi


# Create systemd service file if not exists
SERVICE_FILE="/etc/systemd/system/bramble-rmm-agent.service"
if [ ! -f "$SERVICE_FILE" ]; then
  echo "Creating systemd service..."

  $SUDO tee "$SERVICE_FILE" > /dev/null <<EOF
[Unit]
Description=Bramble RMM Agent
After=network.target

[Service]
ExecStart=$(which node) $INSTALL_DIR/index.js
WorkingDirectory=$INSTALL_DIR
Restart=always
Environment=NODE_ENV=production
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=bramble-rmm-agent
User=root
Group=root

[Install]
WantedBy=multi-user.target
EOF
fi

# Enable and (re)start service — restart (not start) so re-running this
# script to push an update to an already-enrolled device actually picks up
# the newly extracted files, instead of no-op'ing against a running service.
echo "Enabling and starting the service..."
$SUDO systemctl daemon-reload
$SUDO systemctl enable bramble-rmm-agent
$SUDO systemctl restart bramble-rmm-agent

echo "Bramble RMM agent installed and running."
