#!/usr/bin/env bash
# DecisionManager Studio — one-shot install for Linux.
# Discovers VSCodium / Code - OSS / VS Code / Cursor from PATH and common install
# locations (snap, flatpak, /usr/share), installs the VSIX, opens the mode workspace.
#
# Usage:
#   curl -fsSL https://YOUR_SITE/downloads/install-studio-linux.sh | bash
#   INSTALL_MODE=admin BASE_URL=https://YOUR_SITE bash install-studio-linux.sh
#
# Cloud / air-gapped:
#   BASE_URL or STUDIO_BASE_URL  origin that serves /downloads/*.vsix
#   VSIX_URL                     full URL override for the extension package
#   INSTALL_MODE                 manager | server | admin (default manager)
#
set -euo pipefail

PRODUCT="DecisionManager Studio"
MODE="${INSTALL_MODE:-manager}"
case "$MODE" in manager|server|admin) ;; *) MODE=manager ;; esac

BASE_URL="${BASE_URL:-${STUDIO_BASE_URL:-http://localhost:3003}}"
BASE_URL="${BASE_URL%/}"
VSIX_NAME="${VSIX_NAME:-decision-manager-0.4.5.vsix}"
VSIX_URL="${VSIX_URL:-$BASE_URL/downloads/$VSIX_NAME}"
TMP="${TMPDIR:-/tmp}/dm-studio-install-$$"
mkdir -p "$TMP"
trap 'rm -rf "$TMP"' EXIT

echo ""
echo "=== $PRODUCT — Linux install (mode: $MODE) ==="
echo "  base:  $BASE_URL"
echo "  vsix:  $VSIX_URL"
echo ""

is_exec() {
  [[ -n "${1:-}" && -x "$1" && ! -d "$1" ]]
}

path_of() {
  local c
  c="$(command -v "$1" 2>/dev/null || true)"
  if is_exec "$c"; then
    echo "$c"
    return 0
  fi
  return 1
}

well_known_clis() {
  local home="${HOME:-/home/$(id -un)}"
  local candidates=(
    "/usr/bin/codium"
    "/usr/share/vscodium/bin/codium"
    "/usr/bin/code-oss"
    "/usr/bin/code"
    "/usr/share/code/bin/code"
    "/usr/share/code-insiders/bin/code-insiders"
    "/snap/bin/code"
    "/snap/bin/codium"
    "/var/lib/flatpak/exports/bin/com.visualstudio.code"
    "$home/.local/bin/code"
    "$home/.local/bin/codium"
    "/usr/bin/cursor"
    "$home/.local/bin/cursor"
  )
  local p
  for p in "${candidates[@]}"; do
    is_exec "$p" && echo "$p"
  done
}

pick_cli() {
  local found=() name p f already score best="" best_score=999 base
  for name in codium code-oss code code-insiders cursor; do
    if p="$(path_of "$name")"; then
      found+=("$p")
    fi
  done
  while IFS= read -r p; do
    [[ -n "$p" ]] || continue
    already=0
    for f in "${found[@]:-}"; do
      [[ "$f" == "$p" ]] && { already=1; break; }
    done
    [[ $already -eq 0 ]] && found+=("$p")
  done < <(well_known_clis)

  [[ ${#found[@]} -eq 0 ]] && return 1

  for p in "${found[@]}"; do
    base="$(basename "$p")"
    case "$base" in
      codium) score=0 ;;
      code-oss) score=1 ;;
      code) score=2 ;;
      code-insiders) score=3 ;;
      cursor) score=4 ;;
      *) score=5 ;;
    esac
    if [[ $score -lt $best_score ]]; then
      best_score=$score
      best="$p"
    fi
  done
  echo "$best"
}

rerun_cmd() {
  printf 'curl -fsSL "%s/downloads/install-studio-linux.sh" | INSTALL_MODE=%s BASE_URL=%s bash' \
    "$BASE_URL" "$MODE" "$BASE_URL"
}

CLI="$(pick_cli || true)"
if [[ -z "${CLI:-}" ]]; then
  echo "No VSCodium / VS Code / Cursor CLI found on PATH or common install paths."

  # Prefer a single automated path when the host already has a package tool.
  if command -v snap >/dev/null 2>&1; then
    echo "Installing VSCodium via snap (one-time; may prompt for sudo)…"
    if sudo snap install codium --classic; then
      CLI="$(pick_cli || true)"
    fi
  fi
fi

if [[ -z "${CLI:-}" ]]; then
  echo ""
  echo "Next (one preferred path), then this script finishes Studio:"
  if command -v snap >/dev/null 2>&1; then
    echo "  sudo snap install codium --classic && $(rerun_cmd)"
  elif command -v flatpak >/dev/null 2>&1; then
    echo "  # Install VSCodium from https://vscodium.com/#install (or your distro package), then:"
    echo "  $(rerun_cmd)"
  else
    echo "  # Install VSCodium: https://vscodium.com/#install"
    echo "  # Then re-run:"
    echo "  $(rerun_cmd)"
  fi
  echo ""
  echo "Manual VSIX only (after codium/code is on PATH):"
  echo "  curl -fL -o /tmp/$VSIX_NAME \"$VSIX_URL\" && codium --install-extension /tmp/$VSIX_NAME"
  exit 1
fi

CLI_LABEL="$(basename "$CLI")"
echo "Using IDE CLI: $CLI_LABEL"
echo "  path: $CLI"
echo "Downloading extension…"
curl -fL --progress-bar -o "$TMP/$VSIX_NAME" "$VSIX_URL"
echo "Installing…"
"$CLI" --install-extension "$TMP/$VSIX_NAME" --force

# Portable mode workspace — do not open monorepo-relative paths from $TMP
# (EXIT trap deletes TMP; relative folders only work inside the git tree).
STUDIO_HOME="${HOME}/.decision-manager-studio"
mkdir -p "$STUDIO_HOME/workspace"
WS_URL="$BASE_URL/downloads/studio-workspaces/${MODE}.code-workspace"
WS_RAW="$TMP/${MODE}.code-workspace.raw"
WS_FILE="$STUDIO_HOME/${MODE}.code-workspace"

write_portable_workspace() {
  local src="$1" dest="$2" mode="$3"
  if command -v python3 >/dev/null 2>&1; then
    if python3 - "$src" "$dest" "$mode" <<'PY'
import json, sys
src, dest, mode = sys.argv[1], sys.argv[2], sys.argv[3]
try:
    data = json.load(open(src, encoding="utf-8"))
except Exception:
    data = {}
if not isinstance(data, dict):
    data = {}
data["folders"] = [
    {"name": f"DecisionManager Studio ({mode})", "path": "workspace"}
]
data.setdefault("settings", {})
if not isinstance(data["settings"], dict):
    data["settings"] = {}
data.setdefault(
    "extensions",
    {"recommendations": ["decisionmanager.decision-manager"]},
)
json.dump(data, open(dest, "w", encoding="utf-8"), indent=2)
print("ok")
PY
    then
      return 0
    fi
  fi
  cat >"$dest" <<EOF
{
  "folders": [
    { "name": "DecisionManager Studio (${mode})", "path": "workspace" }
  ],
  "settings": {
    "decisionManager.platformUrl": "http://localhost:8081",
    "decisionManager.managerUrl": "http://localhost:8082",
    "decisionManager.runtimeUrl": "http://localhost:8083",
    "decisionManager.adminUrl": "http://localhost:8084",
    "decisionManager.adminConsoleUrl": "http://localhost:3002"
  },
  "extensions": {
    "recommendations": ["decisionmanager.decision-manager"]
  }
}
EOF
}

OPENED=0
if curl -fsSL -o "$WS_RAW" "$WS_URL" 2>/dev/null && [[ -s "$WS_RAW" ]]; then
  if write_portable_workspace "$WS_RAW" "$WS_FILE" "$MODE"; then
    echo "Opening $MODE workspace (portable profile at $WS_FILE)…"
    (cd "$STUDIO_HOME" && "$CLI" "$WS_FILE") || "$CLI" "$WS_FILE" || true
    OPENED=1
  fi
fi

if [[ "$OPENED" -eq 0 ]]; then
  echo '{}' >"$TMP/empty.json"
  write_portable_workspace "$TMP/empty.json" "$WS_FILE" "$MODE" || true
  if [[ -s "$WS_FILE" ]]; then
    echo "Opening $MODE workspace (generated profile at $WS_FILE)…"
    (cd "$STUDIO_HOME" && "$CLI" "$WS_FILE") || "$CLI" "$WS_FILE" || true
    OPENED=1
  fi
fi

if [[ "$OPENED" -eq 0 ]]; then
  echo "Extension installed. Sign in from the palette: Decision Manager: Sign In"
  echo "Configure platformUrl / managerUrl / runtimeUrl / adminUrl (ports 8081–8084)."
  "$CLI" || true
fi

echo ""
echo "=== $PRODUCT ready (mode: $MODE) ==="
echo "  Palette: Decision Manager: Sign In"
echo "  Workspace: $WS_FILE"
echo "  Four URLs: platform :8081 · manager :8082 · runtime :8083 · admin :8084"
echo "  Cloud stack: point BASE_URL at your release host; instance URLs at your APIs."
echo ""
