#!/usr/bin/env bash
# Tests for resolve-account-dir.sh under the multi-account managed-service model
# (Task 983). Registry-membership keep-all: any dir with a valid account.json is
# a registered account and is NEVER swept; the destructive mv is removed (sweep
# is log-only this sprint). Boot resolves ACCOUNT_DIR to the single role:"house".

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RESOLVER="$SCRIPT_DIR/../lib/resolve-account-dir.sh"
PASS=0
FAIL=0
FAILED_TESTS=()

assert_eq() {
  if [ "$1" = "$2" ]; then PASS=$((PASS+1));
  else FAIL=$((FAIL+1)); FAILED_TESTS+=("$3: expected [$2] got [$1]"); fi
}
assert_dir_exists() {
  if [ -d "$1" ]; then PASS=$((PASS+1));
  else FAIL=$((FAIL+1)); FAILED_TESTS+=("$2: dir missing [$1]"); fi
}
assert_dir_absent() {
  if [ ! -d "$1" ]; then PASS=$((PASS+1));
  else FAIL=$((FAIL+1)); FAILED_TESTS+=("$2: dir unexpectedly present [$1]"); fi
}

HOUSE="11111111-1111-1111-1111-111111111111"
CLIENT_A="22222222-2222-2222-2222-222222222222"
CLIENT_B="33333333-3333-3333-3333-333333333333"
ORPHAN="44444444-4444-4444-4444-444444444444"

seed_account() {
  local root="$1" id="$2" role="$3"
  mkdir -p "$root/$id"
  printf '{"accountId":"%s","role":"%s"}\n' "$id" "$role" > "$root/$id/account.json"
}

# --- Test 1: house + 2 clients + 1 orphan; all registered survive, house resolved, nothing trashed ---
run_durability() {
  local tmp; tmp=$(mktemp -d)
  local accounts="$tmp/data/accounts"
  mkdir -p "$accounts"
  seed_account "$accounts" "$CLIENT_A" "client"
  seed_account "$accounts" "$CLIENT_B" "client"
  seed_account "$accounts" "$HOUSE" "house"
  mkdir -p "$accounts/$ORPHAN"  # orphan: no account.json

  local resolved; resolved=$(
    . "$RESOLVER"
    ACCOUNTS_DIR="$accounts" USERS_FILE="/nonexistent/users.json" resolve_and_sweep_account_dir >/dev/null 2>&1
    echo "$ACCOUNT_ID"
  )
  assert_eq "$resolved" "$HOUSE" "house-resolved"
  assert_dir_exists "$accounts/$HOUSE" "house-survives"
  assert_dir_exists "$accounts/$CLIENT_A" "clientA-survives"
  assert_dir_exists "$accounts/$CLIENT_B" "clientB-survives"
  assert_dir_exists "$accounts/$ORPHAN" "orphan-not-trashed"
  assert_dir_absent "$accounts/.trash" "no-trash-created"
  rm -rf "$tmp"
}

# --- Test 2: sole unlabelled account (legacy) resolves as the account ---
run_sole_legacy() {
  local tmp; tmp=$(mktemp -d)
  local accounts="$tmp/data/accounts"
  mkdir -p "$accounts/$HOUSE"
  printf '{"accountId":"%s"}\n' "$HOUSE" > "$accounts/$HOUSE/account.json"  # no role
  local resolved rc
  resolved=$(
    . "$RESOLVER"
    ACCOUNTS_DIR="$accounts" USERS_FILE="/nonexistent/users.json" resolve_and_sweep_account_dir >/dev/null 2>&1
    echo "$ACCOUNT_ID"
  )
  assert_eq "$resolved" "$HOUSE" "sole-legacy-resolved"
  rm -rf "$tmp"
}

# --- Test 3: zero-house with multiple candidates aborts (rc != 0) ---
run_drift_aborts() {
  local tmp; tmp=$(mktemp -d)
  local accounts="$tmp/data/accounts"
  mkdir -p "$accounts"
  seed_account "$accounts" "$CLIENT_A" "client"
  seed_account "$accounts" "$CLIENT_B" "client"
  local rc=0
  (
    . "$RESOLVER"
    ACCOUNTS_DIR="$accounts" USERS_FILE="/nonexistent/users.json" resolve_and_sweep_account_dir >/dev/null 2>&1
  ) || rc=$?
  if [ "$rc" -ne 0 ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); FAILED_TESTS+=("drift-aborts: expected non-zero exit"); fi
  rm -rf "$tmp"
}

run_durability
run_sole_legacy
run_drift_aborts

echo "PASS=$PASS FAIL=$FAIL"
if [ "$FAIL" -gt 0 ]; then
  printf '%s\n' "${FAILED_TESTS[@]}"
  exit 1
fi
