#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# openclaw-bonree-plugin one-line installer
#
# Usage:
#   curl -fsSL https://<oss-host>/install.sh | bash -s -- \
#     --endpoint "https://oneupload.bonree.com/APM/otel" \
#     --account "your-accountGUID" \
#     --set-env-id "env-id" \
#       # x-br-envid, from Deployment Configuration -> Installation Deployment
#     --set-attr "datacenter=1" \
#     --serviceName "my-service" \
#     --sampleRate "1" \
#     --debug
# ---------------------------------------------------------------------------
set -euo pipefail

PLUGIN_NAME="openclaw-bonree-plugin"
# ── Replace with your actual OSS URL after uploading ──
DEFAULT_PLUGIN_URL="https://one.bonree.com/docs/media/openclaw/openclaw-bonree-plugin.tar.gz"

# ── Defaults ──
ENDPOINT=""
BR_ACID=""
BR_ENVID=""
BR_ATTRS=""
SERVICE_NAME=""
SAMPLE_RATE="1"
PLUGIN_URL="${DEFAULT_PLUGIN_URL}"
INSTALL_DIR=""
DEBUG=false

# ── Color helpers ──
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m'

info()  { echo -e "${CYAN}[INFO]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
ok()    { echo -e "${GREEN}[OK]${NC}    $*"; }

# ── Parse arguments ──
need_value() {
  if [[ $# -lt 2 ]] || [[ "$2" == --* ]]; then
    error "Option $1 requires a value"
    exit 1
  fi
}
while [[ $# -gt 0 ]]; do
  case "$1" in
    --endpoint)           need_value "$@"; ENDPOINT="$2";       shift 2 ;;
    --account)            need_value "$@"; BR_ACID="$2";        shift 2 ;;
    --set-env-id)         need_value "$@"; BR_ENVID="$2";       shift 2 ;;
    --set-attr)           need_value "$@"; BR_ATTRS="$2";       shift 2 ;;
    --serviceName)        need_value "$@"; SERVICE_NAME="$2";   shift 2 ;;
    --sampleRate)         need_value "$@"; SAMPLE_RATE="$2";    shift 2 ;;
    --debug)              DEBUG=true; shift ;;
    --plugin-url)         need_value "$@"; PLUGIN_URL="$2";     shift 2 ;;
    --install-dir)        need_value "$@"; INSTALL_DIR="$2";    shift 2 ;;
    *)
      error "Unknown option: $1"
      exit 1
      ;;
  esac
done

# ── Validate required parameters ──
MISSING=()
[[ -z "$ENDPOINT" ]]      && MISSING+=("--endpoint")
[[ -z "$BR_ACID" ]]       && MISSING+=("--account")
[[ -z "$SERVICE_NAME" ]]   && SERVICE_NAME="openclaw-agent"

if [[ ${#MISSING[@]} -gt 0 ]]; then
  error "Missing required parameters: ${MISSING[*]}"
  echo ""
  echo "Usage:"
  echo "  curl -fsSL https://<host>/install.sh | bash -s -- \\"
  echo "    --endpoint \"https://oneupload.bonree.com/APM/otel\" \\"
  echo "    --account \"your-accountGUID\" \\"
  echo "    --set-env-id \"env-id\" \\"
  echo "      # x-br-envid, from Deployment Configuration -> Installation Deployment"
  echo "    --set-attr \"datacenter=1\" \\"
  echo "    --serviceName \"my-service\" \\"
  echo "    --sampleRate \"1\" \\"
  echo "    --debug"
  exit 1
fi

# ── Check prerequisites ──
info "Checking prerequisites..."

if ! command -v node &>/dev/null; then
  error "Node.js is not installed. Please install Node.js >= 18 first."
  exit 1
fi

NODE_MAJOR=$(node -e "process.stdout.write(String(process.versions.node.split('.')[0]))")
if [[ "$NODE_MAJOR" -lt 18 ]]; then
  error "Node.js >= 18 is required (current: $(node --version))"
  exit 1
fi
ok "Node.js $(node --version)"

if ! command -v npm &>/dev/null; then
  error "npm is not installed."
  exit 1
fi
ok "npm $(npm --version)"

OPENCLAW_CMD="openclaw"
if ! command -v "$OPENCLAW_CMD" &>/dev/null; then
  error "OpenClaw CLI not found."
  error "Please install OpenClaw first and make sure the \`openclaw\` command is available in PATH."
  exit 1
else
  ok "OpenClaw CLI found"
fi

# ── Check endpoint connectivity ──
info "Checking endpoint connectivity: ${ENDPOINT}"
ENDPOINT_HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" "$ENDPOINT" -m 10 2>/dev/null || echo "000")
if [[ "$ENDPOINT_HTTP_CODE" == "000" ]]; then
  if echo "$ENDPOINT" | grep -q -- '-intranet\.'; then
    error "Endpoint is unreachable (HTTP code: 000)."
    error "The endpoint appears to be an intranet address."
    error "Please provide a publicly reachable Bonree ONE OTLP endpoint, then re-run the install command."
    exit 1
  else
    error "Endpoint is unreachable (HTTP code: 000)."
    error "Please check your network connectivity to: ${ENDPOINT}"
    error "Data will not be reported if the endpoint is not reachable."
    exit 1
  fi
else
  ok "Endpoint reachable (HTTP ${ENDPOINT_HTTP_CODE})"
fi

# ── Determine install directory ──
if [[ -n "$INSTALL_DIR" ]]; then
  TARGET_DIR="$INSTALL_DIR/extensions/${PLUGIN_NAME}"
elif [[ -n "${OPENCLAW_STATE_DIR:-}" ]] && [[ -d "$OPENCLAW_STATE_DIR" ]]; then
  TARGET_DIR="${OPENCLAW_STATE_DIR}/extensions/${PLUGIN_NAME}"
else
  TARGET_DIR="${HOME}/.openclaw/extensions/${PLUGIN_NAME}"
fi

info "Install directory: ${TARGET_DIR}"

# ── Clean previous installation ──
if [[ -d "$TARGET_DIR" ]]; then
  if [[ -z "$(ls -A "$TARGET_DIR" 2>/dev/null)" ]]; then
    info "Target directory exists but is empty, skipping cleanup."
  elif [[ -f "$TARGET_DIR/package.json" ]] || [[ -f "$TARGET_DIR/openclaw.plugin.json" ]]; then
    info "Removing previous installation..."
    rm -rf "$TARGET_DIR"
  else
    error "Target directory exists but does not look like a plugin installation: ${TARGET_DIR}"
    error "Expected package.json or openclaw.plugin.json inside the directory."
    error "Please verify --install-dir or remove the directory manually."
    exit 1
  fi
fi
mkdir -p "$TARGET_DIR"

# ── Load package archive and extract ──
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
LOCAL_PLUGIN_ARCHIVE="${PWD}/${PLUGIN_NAME}.tar.gz"

if [[ -f "$LOCAL_PLUGIN_ARCHIVE" ]]; then
  info "Found local package archive: ${LOCAL_PLUGIN_ARCHIVE}"
  cp "$LOCAL_PLUGIN_ARCHIVE" "$TMP_DIR/plugin.tar.gz"
  ok "Using local package archive"
elif command -v curl &>/dev/null; then
  info "Downloading plugin from ${PLUGIN_URL}..."
  curl -fsSL -H "Cache-Control: no-cache" "$PLUGIN_URL" -o "$TMP_DIR/plugin.tar.gz"
  ok "Downloaded"
elif command -v wget &>/dev/null; then
  info "Downloading plugin from ${PLUGIN_URL}..."
  wget -q --no-cache "$PLUGIN_URL" -O "$TMP_DIR/plugin.tar.gz"
  ok "Downloaded"
else
  error "Neither curl nor wget is available."
  exit 1
fi

info "Extracting to ${TARGET_DIR}..."
tar -xzf "$TMP_DIR/plugin.tar.gz" -C "$TMP_DIR"
if [[ -d "$TMP_DIR/${PLUGIN_NAME}" ]]; then
  cp -rf "$TMP_DIR/${PLUGIN_NAME}/." "$TARGET_DIR/"
else
  cp -rf "$TMP_DIR/." "$TARGET_DIR/"
fi
ok "Extracted"

# ── Install npm dependencies for openclaw-bonree-plugin ──
info "Installing npm dependencies (production only)..."
cd "$TARGET_DIR"
if ! npm install --omit=dev --ignore-scripts 2>&1; then
  error "npm install failed in ${TARGET_DIR}"
  exit 1
fi
ok "Dependencies installed"

# ── Determine openclaw.json path ──
if [[ -n "${OPENCLAW_STATE_DIR:-}" ]]; then
  CONFIG_PATH="${OPENCLAW_STATE_DIR}/openclaw.json"
elif [[ -f "$HOME/.openclaw/openclaw.json" ]]; then
  CONFIG_PATH="$HOME/.openclaw/openclaw.json"
else
  CONFIG_PATH="$HOME/.openclaw/openclaw.json"
  mkdir -p "$(dirname "$CONFIG_PATH")"
fi

info "Updating config: ${CONFIG_PATH}"

# ── Update openclaw.json using inline Node.js ──
node -e "
const fs = require('fs');
const configPath     = process.argv[1];
const pluginName     = process.argv[2];
const installDir     = process.argv[3];
const endpoint       = process.argv[4];
const brAcid         = process.argv[5];
const brEnvId        = process.argv[6];
const brAttrs        = process.argv[7];
const serviceName    = process.argv[8];
const sampleRateRaw  = process.argv[9];
const debugEnabled   = process.argv[10] === 'true';
const parsedSampleRate = Number(sampleRateRaw);
const sampleRate = Number.isFinite(parsedSampleRate)
  ? Math.max(0, Math.min(1, parsedSampleRate))
  : 1;
const headers        = {
  'x-br-acid': brAcid
};
if (brEnvId) headers['x-br-envid'] = brEnvId;
if (brAttrs) headers['x-br-attrs'] = brAttrs;

let config = {};
try {
  config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
} catch (e) {
  if (e.code !== 'ENOENT') throw e;
}

if (!config.plugins) config.plugins = {};

// ── openclaw-bonree-plugin: plugins.allow ──
if (!Array.isArray(config.plugins.allow)) config.plugins.allow = [];
if (!config.plugins.allow.includes(pluginName)) {
  config.plugins.allow.push(pluginName);
}

// ── openclaw-bonree-plugin: plugins.load.paths ──
if (!config.plugins.load) config.plugins.load = {};
if (!Array.isArray(config.plugins.load.paths)) config.plugins.load.paths = [];
const paths = config.plugins.load.paths;
const idx = paths.findIndex(p => p.includes(pluginName));
if (idx >= 0) paths[idx] = installDir;
else paths.push(installDir);

// ── openclaw-bonree-plugin: plugins.entries ──
if (!config.plugins.entries) config.plugins.entries = {};
config.plugins.entries[pluginName] = {
  enabled: true,
  config: {
    endpoint,
    headers,
    serviceName,
    sampleRate,
    debug: debugEnabled
  }
};

fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
" \
  "$CONFIG_PATH" \
  "$PLUGIN_NAME" \
  "$TARGET_DIR" \
  "$ENDPOINT" \
  "$BR_ACID" \
  "$BR_ENVID" \
  "$BR_ATTRS" \
  "$SERVICE_NAME" \
  "$SAMPLE_RATE" \
  "$DEBUG"

ok "Config updated"

# ── Restart gateway ──
info "Restarting OpenClaw gateway..."
if $OPENCLAW_CMD gateway restart 2>&1; then
  ok "Gateway restarted"
else
  warn "Gateway restart failed. Run manually: openclaw gateway restart"
  warn "If the issue persists, try: openclaw doctor"
fi

# ── Summary ──
echo ""
echo -e "${GREEN}════════════════════════════════════════════════════${NC}"
echo -e "${GREEN}  ✅ openclaw-bonree-plugin installed successfully!${NC}"
echo -e "${GREEN}════════════════════════════════════════════════════${NC}"
echo ""
echo "  Install dir:   ${TARGET_DIR}"
echo "  Config file:   ${CONFIG_PATH}"
echo "  Endpoint:      ${ENDPOINT}"
echo "  Service name:  ${SERVICE_NAME}"
echo "  Sample rate:   ${SAMPLE_RATE}"
echo "  Debug:         ${DEBUG}"
echo ""
