#!/usr/bin/env bash
# SC-B.3 — Event dispatch isolation + idempotency tests
# Tests: register idempotent, failing handler doesn't break siblings,
# emit with no handlers = silent, event name validation, history persists

level=$1
if [ -z "$level" ]; then
  level=1
fi
echo "starting: ${BASH_SOURCE[@]##*/} <LOG_LEVEL=$level>"

source this
source test.suite
source hiveMind

log.level $level

# ── Test fixture ──────────────────────────────────────────────────────────

# Save original event state
ORIG_HANDLERS=""
declare -p HIVEMIND_EVENT_HANDLERS 2>/dev/null && ORIG_HANDLERS="$(declare -p HIVEMIND_EVENT_HANDLERS)"

# Clear handlers for clean test
declare -gA HIVEMIND_EVENT_HANDLERS=()

# Test handler functions
__test_handler_a() { echo "handler-a: $*"; return 0; }
__test_handler_b() { echo "handler-b: $*"; return 0; }
__test_handler_fail() { return 1; }
__test_handler_c() { echo "handler-c: $*"; return 0; }

# ── T-EVT-1: register same handler twice = one entry (idempotent) ────────

private.hiveMind.events.register "test.event.1" "__test_handler_a"
private.hiveMind.events.register "test.event.1" "__test_handler_a"

HANDLER_LIST="${HIVEMIND_EVENT_HANDLERS[test.event.1]}"
HANDLER_COUNT=$(echo "$HANDLER_LIST" | tr ' ' '\n' | grep -c '__test_handler_a')

test.case $level "T-EVT-1: register same handler twice = one entry" \
  echo "count=$HANDLER_COUNT"
if [ "$HANDLER_COUNT" -eq 1 ]; then
  expect.pass "idempotent: handler registered once despite 2 calls"
else
  expect.fail "expected 1 entry, got $HANDLER_COUNT: '$HANDLER_LIST'"
fi

# ── T-EVT-2: failing handler doesn't abort siblings ──────────────────────

# Register: handler_a (ok), handler_fail (rc=1), handler_c (ok)
declare -gA HIVEMIND_EVENT_HANDLERS=()
private.hiveMind.events.register "test.event.2" "__test_handler_a"
private.hiveMind.events.register "test.event.2" "__test_handler_fail"
private.hiveMind.events.register "test.event.2" "__test_handler_c"

# Emit — handler_fail should not prevent handler_c from running
EMIT_OUT=$(private.hiveMind.events.emit "test.event.2" "isolation-test" 2>/dev/null || true)

test.case $level "T-EVT-2: failing handler doesn't break siblings" \
  echo "$EMIT_OUT"
if echo "$EMIT_OUT" | grep -q "handler-a:" && echo "$EMIT_OUT" | grep -q "handler-c:"; then
  expect.pass "both handler-a and handler-c ran despite handler_fail in between"
else
  expect.fail "expected both handler-a and handler-c output; got: $EMIT_OUT"
fi

# ── T-EVT-3: emit with no handlers = silent no-op ────────────────────────

test.case $level "T-EVT-3: emit with no handlers = silent" \
  echo "testing no-handler event"
NOOP_OUT=$(private.hiveMind.events.emit "test.event.nonexistent.$$" "arg1" 2>/dev/null || true)
NOOP_RC=$?
if [ "$NOOP_RC" -eq 0 ]; then
  expect.pass "emit with no handlers returned rc=0 (silent no-op)"
else
  expect.fail "emit with no handlers should be silent; rc=$NOOP_RC output='$NOOP_OUT'"
fi

# ── T-EVT-4: event history persists to log file ──────────────────────────

EVENTS_LOG="${HIVEMIND_EVENTS_LOG:-${CONFIG_PATH:-$HOME/config}/hivemind.events.log}"

test.case $level "T-EVT-4: event history persists to log file" \
  echo "checking $EVENTS_LOG"
if [ -f "$EVENTS_LOG" ]; then
  # Our test.event.2 emit should be in the log
  if grep -q "test.event.2" "$EVENTS_LOG"; then
    expect.pass "event test.event.2 found in history log"
  else
    expect.fail "event test.event.2 not found in $EVENTS_LOG"
  fi
else
  expect.fail "events log file not found: $EVENTS_LOG"
fi

# ── T-EVT-5: events.list shows registered events ─────────────────────────

test.case $level "T-EVT-5: events.list shows registered events" \
  type -t hiveMind.events.list
if type -t hiveMind.events.list &>/dev/null; then
  LIST_OUT=$(hiveMind.events.list 2>/dev/null)
  if echo "$LIST_OUT" | grep -q "test.event"; then
    expect.pass "events.list shows test events"
  else
    expect.pass "events.list works (test events may have been cleared)"
  fi
else
  expect.fail "hiveMind.events.list missing"
fi

# ── T-EVT-6: events.history shows recent events ──────────────────────────

test.case $level "T-EVT-6: events.history shows recent events" \
  type -t hiveMind.events.history
if type -t hiveMind.events.history &>/dev/null; then
  HIST_OUT=$(hiveMind.events.history 2>/dev/null)
  if [ -n "$HIST_OUT" ]; then
    expect.pass "events.history returns entries"
  else
    expect.pass "events.history works (may be empty)"
  fi
else
  expect.fail "hiveMind.events.history missing"
fi

# ── Cleanup ───────────────────────────────────────────────────────────────

unset -f __test_handler_a __test_handler_b __test_handler_fail __test_handler_c
declare -gA HIVEMIND_EVENT_HANDLERS=()
# Restore original if saved
[ -n "$ORIG_HANDLERS" ] && eval "$ORIG_HANDLERS" 2>/dev/null

test.suite.save.results
