#!/usr/bin/env bash
# Covers the brain-home fleet-state check in `mosaic-doctor` (#1298 follow-up).
#
# The functions are extracted from the shipped script rather than copied here
# (same discipline as test-fleet-transport-check.sh): a test that carries its
# own copy of the logic keeps passing after the shipped copy changes.
# Extraction is by exact function header and a closing brace in column one.
set -euo pipefail

SCRIPT_DIR=$(cd -- "$(dirname "$0")" && pwd)
DOCTOR="$SCRIPT_DIR/mosaic-doctor"

fail() {
  echo "FAIL: $*" >&2
  exit 1
}

[ -f "$DOCTOR" ] || fail "missing mosaic-doctor at $DOCTOR"

extract_function() {
  local name="$1"
  local extracted
  extracted=$(sed -n "/^${name}() {/,/^}/p" "$DOCTOR")
  [ -n "$extracted" ] || fail "could not extract ${name}() from mosaic-doctor — script reshaped?"
  printf '%s\n' "$extracted"
}

for fn in resolve_brain_home check_brain_home; do
  extract_function "$fn" >/dev/null
done

warn_count=0
warn() { warn_count=$((warn_count + 1)); echo "[WARN] $*"; }
pass() { echo "[OK] $*"; return 0; }

eval "$(extract_function resolve_brain_home)"
eval "$(extract_function check_brain_home)"

ROOT=$(mktemp -d)
trap 'rm -rf "$ROOT"' EXIT

# note output is neither [OK] nor [WARN] — assert it directly in the case below.
run_case() {
  # label, expect (ok|warn|note), then env assignments as arguments.
  # The check runs under `env` in a subshell, so its warn() also prints a
  # sentinel the parent counts — a subshell counter would never be visible.
  local label="$1" expect="$2"
  shift 2
  local out warns notes
  out=$(env "$@" bash -c "warn() { echo \"[WARN] \$*\"; }; note() { echo \"[NOTE] \$*\"; return 0; }; pass() { echo \"[OK] \$*\"; return 0; }; $(extract_function resolve_brain_home); $(extract_function check_brain_home); check_brain_home" 2>&1)
  warns=$(printf '%s\n' "$out" | grep -c '^\[WARN\]' || true)
  notes=$(printf '%s\n' "$out" | grep -c '^\[NOTE\]' || true)
  if [[ "$expect" == ok && "$warns" -eq 0 && "$notes" -eq 0 ]]; then
    echo "ok - $label"
  elif [[ "$expect" == warn && "$warns" -gt 0 ]]; then
    echo "ok - $label (warned)"
  elif [[ "$expect" == note && "$notes" -gt 0 ]]; then
    echo "ok - $label (noted)"
  else
    echo "output: $out" >&2
    fail "$label: expected $expect (warns=$warns notes=$notes)"
  fi
}

# ── legacy: no brain, custom home never adopts ─────────────────────────────
mkdir -p "$ROOT/legacy-mosaic/fleet/agents"
run_case "custom home without brain stays legacy" ok \
  MOSAIC_HOME="$ROOT/legacy-mosaic" HOME="$ROOT"

# ── healthy brain at the default config home ───────────────────────────────
mkdir -p "$ROOT/home/.config/mosaic" "$ROOT/home/.mosaic/fleet/agents"
chmod 700 "$ROOT/home/.mosaic/fleet/agents"
run_case "default home adopts healthy brain" ok \
  MOSAIC_HOME="$ROOT/home/.config/mosaic" HOME="$ROOT/home"

# ── explicit MOSAIC_BRAIN_HOME to a brain without fleet/agents → warn ──────
mkdir -p "$ROOT/brain-noagents/fleet" "$ROOT/config"
run_case "explicit brain without agents warns" warn \
  MOSAIC_HOME="$ROOT/config" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-noagents"

# ── explicit MOSAIC_BRAIN_HOME to a healthy brain → ok ─────────────────────
mkdir -p "$ROOT/brain-ok/fleet/agents" "$ROOT/config2"
chmod 700 "$ROOT/brain-ok/fleet/agents"
run_case "explicit healthy brain passes" ok \
  MOSAIC_HOME="$ROOT/config2" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-ok"

# ── group-readable agents dir → warn (0700 boundary) ───────────────────────
mkdir -p "$ROOT/brain-loose/fleet/agents" "$ROOT/config3"
chmod 750 "$ROOT/brain-loose/fleet/agents"
run_case "group-readable brain agents warns" warn \
  MOSAIC_HOME="$ROOT/config3" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-loose"

# ── symlinked agents dir → warn (managed-directory boundary) ───────────────
mkdir -p "$ROOT/brain-link/real-agents" "$ROOT/brain-link/fleet" "$ROOT/config4"
ln -s "$ROOT/brain-link/real-agents" "$ROOT/brain-link/fleet/agents"
run_case "symlinked brain agents warns" warn \
  MOSAIC_HOME="$ROOT/config4" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-link"

# ── split state: envs in BOTH trees → warn ─────────────────────────────────
mkdir -p "$ROOT/brain-split/fleet/agents" "$ROOT/config5/fleet/agents"
chmod 700 "$ROOT/brain-split/fleet/agents" "$ROOT/config5/fleet/agents"
touch "$ROOT/config5/fleet/agents/coder0.env.generated"
run_case "env files in both trees warns (split state)" warn \
  MOSAIC_HOME="$ROOT/config5" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-split"

# ── config-home agents dir WITHOUT env files alongside a brain → ok ────────
mkdir -p "$ROOT/brain-clean/fleet/agents" "$ROOT/config6/fleet/agents"
chmod 700 "$ROOT/brain-clean/fleet/agents" "$ROOT/config6/fleet/agents"
run_case "empty config-home agents dir alongside brain passes" ok \
  MOSAIC_HOME="$ROOT/config6" HOME="$ROOT" MOSAIC_BRAIN_HOME="$ROOT/brain-clean"

# ── greenfield brain-without-agents at the default home → note (#1288) ─────
mkdir -p "$ROOT/gf-home/.config/mosaic/fleet" "$ROOT/gf-home/.mosaic"
run_case "~/.mosaic without fleet/agents at default home notes the lock-in" note \
  MOSAIC_HOME="$ROOT/gf-home/.config/mosaic" HOME="$ROOT/gf-home"

# ── no ~/.mosaic at all at the default home → clean pass ─────────────────
mkdir -p "$ROOT/plain-home/.config/mosaic/fleet"
run_case "no ~/.mosaic at default home passes silently" ok \
  MOSAIC_HOME="$ROOT/plain-home/.config/mosaic" HOME="$ROOT/plain-home"

# ── custom (non-default) home with a stray ~/.mosaic → still silent ──────
mkdir -p "$ROOT/custom-home/fleet/agents" "$ROOT/custom-home/.mosaic"
run_case "custom home with stray ~/.mosaic stays silent" ok \
  MOSAIC_HOME="$ROOT/custom-home" HOME="$ROOT/custom-home"

echo "ok - mosaic-doctor brain-home check"
