#!/usr/bin/env bash

# Installs MBS Plugin on a FileMaker Server for macOS

# download this script, mark it as executable and run:
# curl -LO https://www.monkeybreadsoftware.com/filemaker/files/gzip/macinstall.sh
# chmod +x macinstall.sh
# sudo ./macinstall.sh

set -euo pipefail
umask 022


# -----------------------------
# 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
  [[ "$USE_EMOJI" -eq 1 ]] && echo "ℹ️  $*" || echo "INFO:  $*"
}

log_ok() {
  [[ "$SILENT" -eq 1 ]] && return
  [[ "$USE_EMOJI" -eq 1 ]] && echo "✅ $*" || echo "OK:    $*"
}

log_warn() {
  [[ "$USE_EMOJI" -eq 1 ]] && echo "⚠️  $*" >&2 || echo "WARN:  $*" >&2
}

log_error() {
  [[ "$USE_EMOJI" -eq 1 ]] && echo "❌ $*" >&2 || echo "ERROR: $*" >&2
}

log_emoji() {
  [[ "$SILENT" -eq 1 ]] && return
  local prefix="$1"; shift
  [[ "$USE_EMOJI" -eq 1 ]] && echo "${prefix} $*" || echo "INFO: $*"
}

log_info "=== MBS Plugin Installer (macOS) ==="


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


# -----------------------------
# 2. Architecture detection
# -----------------------------
ARCH="$(uname -m)"
case "$ARCH" in
  x86_64)
    CPU_TYPE="Intel"
    ;;
  arm64)
    CPU_TYPE="Apple Silicon"
    ;;
  *)
    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 (macOS)
# -----------------------------
PLUGIN_DIRS=(
  "/Library/FileMaker Server/Database Server/Extensions"
  "/Library/FileMaker Server/Web Publishing/publishing-engine/cwpc/Plugins"
  "/Library/FileMaker Server/Web Publishing/publishing-engine/wip/Plugins"
)


# -----------------------------
# 5. Download info
# -----------------------------
MBS_URL="https://www.monkeybreadsoftware.com/filemaker/files/gzip/MBS.fmplugin.gz"


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

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


# -----------------------------
# 7. 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

[[ -s "$PLUGIN_GZ" ]] || { log_error "Downloaded file is empty"; exit 1; }
log_ok "Download successful"


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


# -----------------------------
# 9. Extract plugin
# -----------------------------
log_emoji "📦" "Extracting plugin archive..."

XAR_FILE="$TMP_DIR/MBS.fmplugin.xar"
PLUGIN_BUNDLE="$TMP_DIR/MBS.fmplugin"

# Decompress gzip to a known filename
gunzip -c "$PLUGIN_GZ" > "$XAR_FILE"

# Sanity check
if [[ ! -s "$XAR_FILE" ]]; then
  log_error "gunzip failed: XAR file is empty"
  exit 1
fi

# Extract XAR archive
xar -xf "$XAR_FILE" -C "$TMP_DIR"

if [[ ! -d "$PLUGIN_BUNDLE" ]]; then
  log_error "Extraction failed: MBS.fmplugin bundle not found"
  exit 1
fi

log_ok "Plugin bundle extracted successfully"

# -----------------------------
# 10. Validate Mach-O binary
# -----------------------------
EXECUTABLE="$(find "$PLUGIN_FILE" -type f -perm +111 | head -n 1)"

if [[ -z "$EXECUTABLE" ]]; then
  log_error "No executable found inside plugin bundle"
  exit 1
fi

FILE_INFO="$(file "$EXECUTABLE")"

if ! echo "$FILE_INFO" | grep -q "Mach-O"; then
  log_error "Plugin executable is not Mach-O"
  log_error "Detected: $FILE_INFO"
  exit 1
fi

log_ok "Mach-O executable verified"


# -----------------------------
# 10b. Code signature validation
# -----------------------------
log_emoji "🔐" "Verifying code signature..."

CODESIGN_INFO="$(codesign -dv --verbose=4 "$PLUGIN_BUNDLE" 2>&1 || true)"

if ! echo "$CODESIGN_INFO" | grep -q 'Authority=Developer ID Application: Christian Schmitz Software GmbH (RZ52899P4B)'; then
  log_error "Code signature validation failed"
  log_error "Expected Authority:"
  log_error "  Developer ID Application: Christian Schmitz Software GmbH (RZ52899P4B)"
  log_error "Detected signature info:"
  echo "$CODESIGN_INFO"
  exit 1
fi

log_ok "Code signature verified (Christian Schmitz Software GmbH)"


# -----------------------------
# 11. File size check (>20 MB)
# -----------------------------
MIN_SIZE_MB=20

# macOS-safe recursive directory size (bytes)
DIR_SIZE_BYTES=$(du -sk "$PLUGIN_FILE" | awk '{print $1 * 1024}')
MIN_SIZE_BYTES=$((MIN_SIZE_MB * 1024 * 1024))

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

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


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


# remove quarantine if needed
xattr -r -d com.apple.quarantine "$PLUGIN_FILE"

# -----------------------------
# 13. Install plugin
# -----------------------------
for DIR in "${PLUGIN_DIRS[@]}"; do
  if [[ -d "$DIR" ]]; then
    log_emoji "📁" "Installing to: $DIR"

    TARGET="$DIR/MBS.fmplugin"

    # Remove existing plugin to avoid mixed versions
    if [[ -d "$TARGET" ]]; then
      log_emoji "🧹" "Removing existing plugin bundle"
      rm -rf "$TARGET"
    fi

    # Copy new bundle
    cp -R "$PLUGIN_BUNDLE" "$DIR/"

    # Ensure safe permissions
    chmod -R a+rX,go-w "$TARGET"

  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) and enable the plugin in Admin Console."
