#!/usr/bin/env bash

# Installs MBS Plugin on a FileMaker Server for Linux

# download this script, mark it as executable and run:

# curl -LO https://www.monkeybreadsoftware.com/filemaker/files/gzip/linuxinstall.sh
# chmod +x linuxinstall.sh
# sudo ./linuxinstall.sh


# optional arguments --silent|-s for silent and --no-emoji to disable emojis. Emojis are automatically disabled if not supported by the Terminal.

# What the script does

# Verifies you are running on Linux
# Detects CPU architecture (Intel or ARM)
# Downloads the correct MBS plugin securely (HTTPS)
# Verifies:
# * Download success
# * Gzip integrity
# * ELF binary type
# * Correct architecture
# * Minimum size (> 30 MB)
# Installs MBS.fmx into:
# * Database Server/Extensions
# * Web Publishing (cwpc) Plugins
# * Data API (wip) Plugins
# Sets safe permissions (644)


set -euo pipefail
umask 022


# Check Flags

SILENT=0
NO_EMOJI=0

for arg in "$@"; do
  case "$arg" in
    --silent|-s)
      SILENT=1
      NO_EMOJI=1
      ;;
    --no-emoji)
      NO_EMOJI=1
      ;;
  esac
done


supports_emoji() {
  [[ -t 1 ]] || return 1
  [[ "${TERM:-}" != "dumb" ]] || return 1
  locale | grep -qi 'utf-8' || return 1
  return 0
}

USE_EMOJI=1
if [[ "$NO_EMOJI" -eq 1 ]] || ! supports_emoji; then
  USE_EMOJI=0
fi

log_info() {
  [[ "$SILENT" -eq 1 ]] && return
  if [[ "$USE_EMOJI" -eq 1 ]]; then
    echo "ℹ️  $*"
  else
    echo "INFO:  $*"
  fi
}

log_ok() {
  [[ "$SILENT" -eq 1 ]] && return
  if [[ "$USE_EMOJI" -eq 1 ]]; then
    echo "✅ $*"
  else
    echo "OK:    $*"
  fi
}

log_warn() {
  if [[ "$USE_EMOJI" -eq 1 ]]; then
    echo "⚠️  $*" >&2
  else
    echo "WARN:  $*" >&2
  fi
}

log_error() {
  if [[ "$USE_EMOJI" -eq 1 ]]; then
    echo "❌ $*" >&2
  else
    echo "ERROR: $*" >&2
  fi
}

# $1 = emoji or ASCII prefix
# $2.. = message
log_emoji() {
  [[ "$SILENT" -eq 1 ]] && return

  local prefix="$1"
  shift

  if [[ "$USE_EMOJI" -eq 1 ]]; then
    echo "${prefix} $*"
  else
    # Fallback: strip emoji and use ASCII
    echo "INFO: $*"
  fi
}

log_info "=== MBS Plugins Installer ==="



# -----------------------------
# 1. OS check
# -----------------------------
if [[ "$(uname -s)" != "Linux" ]]; then
  log_error "This installer only supports Linux."
  exit 1
fi
log_ok "Linux detected"

# -----------------------------
# 2. Architecture detection
# -----------------------------
ARCH="$(uname -m)"

case "$ARCH" in
  x86_64|amd64)
    CPU_TYPE="intel"
    EXPECTED_FILE_ARCH="x86-64"
    MBS_URL="https://monkeybreadsoftware.com/filemaker/files/gzip/MBS.fmx.gz"
    ;;
  aarch64|arm64)
    CPU_TYPE="arm"
    EXPECTED_FILE_ARCH="aarch64"
    MBS_URL="https://monkeybreadsoftware.com/filemaker/files/gzip/MBS.fmx.arm.gz"
    ;;
  *)
    log_error "Unsupported architecture: $ARCH"
    exit 1
    ;;
esac

log_ok "CPU architecture: $CPU_TYPE ($ARCH)"

# -----------------------------
# 3. Privilege check
# -----------------------------
if [[ "$EUID" -ne 0 ]]; then
  log_error "Must be run with sudo."
  log_emoji "👉" "sudo $0"
  exit 1
fi
log_ok "Running as root"

# -----------------------------
# 4. FileMaker plugin directories
# -----------------------------
PLUGIN_DIRS=(
  "/opt/FileMaker/FileMaker Server/Web Publishing/publishing-engine/cwpc/Plugins"
  "/opt/FileMaker/FileMaker Server/Database Server/Extensions"
  "/opt/FileMaker/FileMaker Server/Web Publishing/publishing-engine/wip/Plugins"
)

# -----------------------------
# 5. Temporary workspace
# -----------------------------
TMP_DIR="$(mktemp -d)"
PLUGIN_GZ="$TMP_DIR/MBS.fmx.gz"
PLUGIN_FILE="$TMP_DIR/MBS.fmx"

cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT

# -----------------------------
# 6. Secure download
# -----------------------------
log_emoji "📥" "Downloading MBS plugin..."

HTTP_CODE=$(curl \
  --fail \
  --silent \
  --show-error \
  --location \
  --proto '=https' \
  --tlsv1.2 \
  --write-out "%{http_code}" \
  -o "$PLUGIN_GZ" \
  "$MBS_URL"
)

if [[ "$HTTP_CODE" != "200" ]]; then
  log_error "Download failed (HTTP $HTTP_CODE)"
  exit 1
fi

if [[ ! -s "$PLUGIN_GZ" ]]; then
  log_error "Downloaded file is empty"
  exit 1
fi

log_ok "Download successful"

# -----------------------------
# 7. Validate gzip integrity
# -----------------------------
log_emoji "🔍" "Verifying gzip integrity..."
gzip -t "$PLUGIN_GZ"
log_ok "Gzip archive is valid"

# -----------------------------
# 8. Extract plugin
# -----------------------------
log_emoji "📦" "Extracting plugin..."
gunzip "$PLUGIN_GZ"

if [[ ! -f "$PLUGIN_FILE" ]]; then
  log_error "Extraction failed: MBS.fmx not found"
  exit 1
fi

# -----------------------------
# 9. Validate file type & architecture
# -----------------------------
FILE_INFO="$(file "$PLUGIN_FILE")"

if ! echo "$FILE_INFO" | grep -q "ELF"; then
  log_error "Plugin is not an ELF binary"
  echo "   Detected: $FILE_INFO"
  exit 1
fi

if ! echo "$FILE_INFO" | grep -q "$EXPECTED_FILE_ARCH"; then
  log_error "Architecture mismatch"
  log_error "   Expected: $EXPECTED_FILE_ARCH"
  log_error "   Detected: $FILE_INFO"
  exit 1
fi

log_ok "ELF and architecture verified"

# -----------------------------
# 10. File size check (>30 MB)
# -----------------------------
MIN_SIZE_MB=30
FILE_SIZE_BYTES=$(stat -c%s "$PLUGIN_FILE")
MIN_SIZE_BYTES=$((MIN_SIZE_MB * 1024 * 1024))

if [[ "$FILE_SIZE_BYTES" -lt "$MIN_SIZE_BYTES" ]]; then
  log_error "Plugin file too small"
  log_error "   Size: $((FILE_SIZE_BYTES / 1024 / 1024)) MB"
  log_error "   Expected: > ${MIN_SIZE_MB} MB"
  exit 1
fi

log_ok "Plugin size verified (> ${MIN_SIZE_MB} MB)"

# -----------------------------
# 11. Permissions
# -----------------------------
chmod 644 "$PLUGIN_FILE"
log_ok "Plugin permissions set (644)"

# -----------------------------
# 12. Install plugin
# -----------------------------
for DIR in "${PLUGIN_DIRS[@]}"; do
  if [[ -d "$DIR" ]]; then
    log_emoji "📁" "Installing to: $DIR"
    rm -f "$DIR"/MBS*.fmx || true
    cp -f "$PLUGIN_FILE" "$DIR/MBS.fmx"
    chmod 644 "$DIR/MBS.fmx"
  else
    log_warn "Directory not found, skipping: $DIR"
  fi
done

log_emoji "🎉" "MBS Plugin installation completed successfully."
log_info "Restart FileMaker Server (Script Engine, Data API and Web Direct) to activate the new plugin and enable them in admin-console."


