#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
PASS=0
FAIL=0

ok() { PASS=$((PASS+1)); printf '  ok   %s\n' "$1"; }
bad() { FAIL=$((FAIL+1)); printf '  FAIL %s\n     %s\n' "$1" "$2"; }

mkfixture() {
  local dir
  dir="$(mktemp -d "/tmp/ca-session-XXXX")"
  mkdir -p "$dir/wrappers" "$dir/bin"
  cp "$ROOT/wrappers/ca.sh" "$dir/wrappers/ca.sh"
  mkdir -p "$dir/wrappers/lib"
  cp "$ROOT/wrappers/lib/verdict-status.py" "$dir/wrappers/lib/verdict-status.py"
  chmod +x "$dir/wrappers/ca.sh"
  : > "$dir/CURSOR.env"
  printf '%s\n' "$dir"
}

write_mock_cursor() {
  local dir="$1"
  cat > "$dir/bin/cursor-agent" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

log_file="${MOCK_LOG_FILE:?}"
printf '%s\n' "$*" >> "$log_file"

if [[ "${1:-}" == "create-chat" ]]; then
  printf '%s\n' "${MOCK_CHAT_ID:-chat-mock-123}"
  exit 0
fi

if [[ "${1:-}" == "status" ]]; then
  if [[ -n "${MOCK_STATUS_JSON+x}" ]]; then
    status_json="$MOCK_STATUS_JSON"
  else
    status_json='{"ok":true}'
  fi
  printf '%s\n' "$status_json"
  exit "${MOCK_STATUS_EXIT_CODE:-0}"
fi

if [[ "${1:-}" == "models" ]]; then
  printf '%s\n' "${MOCK_MODELS_OUTPUT:-composer-2.5}"
  exit "${MOCK_MODELS_EXIT_CODE:-0}"
fi

printf '%s\n' "${MOCK_RUN_OUTPUT-{\"event\":\"done\"\}}"
exit "${MOCK_RUN_EXIT_CODE:-0}"
EOF
  chmod +x "$dir/bin/cursor-agent"
}

run_dispatch_case() {
  local dir out rc status_line log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    MOCK_CHAT_ID="chat-abc-123" \
    MOCK_RUN_OUTPUT='{"type":"result","detail":"done"}' \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" \
      --workspace "$dir" \
      --trust "ship it" \
      --task-slug "task-1" \
      --model "composer-2.5" \
      --timeout 30 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  if [[ "$rc" -eq 0 ]]; then
    ok "dispatch exits zero"
  else
    bad "dispatch exits zero" "rc=$rc out=${out:-<empty>}"
  fi

  if grep -Fxq 'create-chat' "$log_file"; then
    ok "dispatch creates a chat before running agent"
  else
    bad "dispatch creates a chat before running agent" "$(cat "$log_file")"
  fi

  if grep -Fq -- '--resume chat-abc-123' "$log_file"; then
    ok "dispatch binds agent run to created chat id"
  else
    bad "dispatch binds agent run to created chat id" "$(cat "$log_file")"
  fi

  if grep -Fq -- '--model composer-2.5' "$log_file"; then
    ok "dispatch pins model on run line"
  else
    bad "dispatch pins model on run line" "$(cat "$log_file")"
  fi

  status_line="$(printf '%s\n' "$out" | tail -n 1)"
  if printf '%s\n' "$status_line" | grep -Fq '"thread_id":"chat-abc-123"'; then
    ok "dispatch prints final continuity status line"
  else
    bad "dispatch prints final continuity status line" "${status_line:-<empty>}"
  fi

  rm -rf "$dir"
}

run_verdict_case() {
  local dir out rc status_line log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    MOCK_CHAT_ID="chat-verdict-1" \
    MOCK_RUN_OUTPUT='{"type":"result","result":"Checked the diff.\n{\"clean\":true,\"findings\":[]}\n## Review summary\n\nLooks fine."}' \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" \
      --workspace "$dir" \
      --trust "review it" \
      --task-slug "task-review" \
      --model "composer-2.5" \
      --timeout 30 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  status_line="$(printf '%s\n' "$out" | tail -n 1)"
  if [[ "$rc" -eq 0 ]] && printf '%s\n' "$status_line" \
    | python3 -c 'import json,sys; r=json.loads(sys.stdin.read()); sys.exit(0 if r=={"clean":True,"findings":[],"thread_id":"chat-verdict-1"} else 1)'; then
    ok "dispatch surfaces agent verdict as the status line"
  else
    bad "dispatch surfaces agent verdict as the status line" "rc=$rc ${status_line:-<empty>}"
  fi

  rm -rf "$dir"
}

run_resume_case() {
  local dir out rc log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" \
      --workspace "$dir" \
      --trust "resume it" \
      --task-slug "task-2" \
      --model "composer-2.5" \
      --resume "chat-existing-9" \
      --timeout 30 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  if [[ "$rc" -eq 0 ]]; then
    ok "resume dispatch exits zero"
  else
    bad "resume dispatch exits zero" "rc=$rc out=${out:-<empty>}"
  fi

  if [[ "$(grep -c '^create-chat$' "$log_file" || true)" -eq 0 ]]; then
    ok "resume dispatch skips create-chat pre-step"
  else
    bad "resume dispatch skips create-chat pre-step" "$(cat "$log_file")"
  fi

  if grep -Fq -- '--resume chat-existing-9' "$log_file"; then
    ok "resume dispatch forwards explicit chat id"
  else
    bad "resume dispatch forwards explicit chat id" "$(cat "$log_file")"
  fi

  rm -rf "$dir"
}

run_health_case() {
  local dir out rc log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    MOCK_STATUS_JSON='{"authenticated":true}' \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" --health 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  if [[ "$rc" -eq 0 ]] && [[ "$out" == '{"authenticated":true}' ]]; then
    ok "health mode proxies cursor status json"
  else
    bad "health mode proxies cursor status json" "rc=$rc out=${out:-<empty>}"
  fi

  if grep -Fxq 'status --format json' "$log_file"; then
    ok "health mode calls cursor status json"
  else
    bad "health mode calls cursor status json" "$(cat "$log_file")"
  fi

  rm -rf "$dir"
}

run_missing_env_case() {
  local dir out rc log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"
  rm -f "$dir/CURSOR.env"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    MOCK_STATUS_JSON='{"authenticated":true}' \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" --health 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  if [[ "$rc" -eq 0 ]] && [[ "$out" == '{"authenticated":true}' ]]; then
    ok "missing CURSOR.env is not fatal"
  else
    bad "missing CURSOR.env is not fatal" "rc=$rc out=${out:-<empty>}"
  fi

  rm -rf "$dir"
}

run_list_models_case() {
  local dir out rc log_file
  dir="$(mkfixture)"
  write_mock_cursor "$dir"
  log_file="$dir/invocations.log"
  : > "$log_file"

  if out=$(
    PATH="$dir/bin:$PATH" \
    MOCK_LOG_FILE="$log_file" \
    MOCK_MODELS_OUTPUT=$'model-a\nmodel-b' \
    HOME="$dir/home" \
    "$dir/wrappers/ca.sh" --list-models 2>&1
  ); then
    rc=0
  else
    rc=$?
  fi

  if [[ "$rc" -eq 0 ]] && [[ "$out" == $'model-a\nmodel-b' ]]; then
    ok "list-models mode proxies model listing"
  else
    bad "list-models mode proxies model listing" "rc=$rc out=${out:-<empty>}"
  fi

  if grep -Fxq 'models' "$log_file"; then
    ok "list-models mode calls cursor models"
  else
    bad "list-models mode calls cursor models" "$(cat "$log_file")"
  fi

  rm -rf "$dir"
}

echo "ca session continuity:"
run_dispatch_case
run_verdict_case
run_resume_case
run_health_case
run_missing_env_case
run_list_models_case
echo
echo "PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]]
