#!/usr/bin/env zsh

set -u

typeset -r repo_dir="${0:A:h}"
source "$repo_dir/plan_build.zsh"

typeset -gi failures=0
functions[_plan_build_real_launch_claude]="${functions[_plan_build_launch_claude]}"
functions[_plan_build_real_enhance_prompt]="${functions[_plan_build_enhance_prompt]}"
functions[_plan_build_real_start_auggie_script]="${functions[_plan_build_start_auggie_script]}"

fail() {
  print -u2 -r -- "FAIL: $1"
  failures=$((failures + 1))
}

assert_equal() {
  local expected="$1" actual="$2" label="$3"
  [[ "$actual" == "$expected" ]] || fail "$label (expected '$expected', got '$actual')"
}

assert_contains() {
  local output="$1" expected="$2" label="$3"
  [[ "$output" == *"$expected"* ]] || fail "$label (missing '$expected')"
}

assert_not_contains() {
  local output="$1" unexpected="$2" label="$3"
  [[ "$output" != *"$unexpected"* ]] || fail "$label (unexpected '$unexpected')"
}

run_plan() {
  local args="$1" input="${2:-EOF\n}"
  output="$(printf '%b' "$input" | plan_build ${(z)args} 2>&1)"
  rc=$?
}

seam_events() {
  print -r -- "$1" | sed -n 's/^SEAM://p' | paste -sd ' ' -
}

count_matches() {
  local directory="$1" prefix="$2"
  local -a matches
  matches=("$directory"/"$prefix".*(N))
  print -r -- "$#matches"
}

typeset fixture_dir
fixture_dir="$(mktemp -d "${TMPDIR:-/tmp}/plan-build-tests.XXXXXX")" || exit 1
trap 'rm -rf -- "$fixture_dir"' EXIT
mkdir -p "$fixture_dir/tmp"
export TMPDIR="$fixture_dir/tmp"

command git init -q "$fixture_dir/worktree"
command git init -q --bare "$fixture_dir/bare.git"

(cd "$fixture_dir/worktree" && _plan_build_is_worktree)
assert_equal 0 "$?" "normal Git worktree accepted"
(cd "$fixture_dir/bare.git" && _plan_build_is_worktree)
assert_equal 1 "$?" "bare Git repository rejected"
(cd "$fixture_dir" && _plan_build_is_worktree)
assert_equal 1 "$?" "non-repository rejected"

plugin_state() {
  print -r -- "$1" | _plan_build_superpowers_state
}

assert_equal enabled "$(plugin_state '[{"id":"superpowers@claude-plugins-official","enabled":true}]')" "enabled plugin JSON"
assert_equal disabled "$(plugin_state $'[\n{"enabled":false,\n"id":"superpowers@claude-plugins-official"}\n]')" "reordered disabled plugin JSON"
assert_equal missing "$(plugin_state '[{"id":"other@market","enabled":true}]')" "missing plugin JSON"
assert_equal installed "$(plugin_state '[{"id":"superpowers@claude-plugins-official"}]')" "installed plugin JSON"

typeset args expected label
for args expected label in \
  "--v2" "Unknown argument: --v2" "v2 rejection" \
  "--unknown" "Unknown argument: --unknown" "unknown option" \
  "--yolo --yolo" "Duplicate argument: --yolo" "duplicate yolo" \
  "--prompt --prompt" "Duplicate argument: --prompt" "duplicate prompt" \
  "--brainstorm --brainstorm" "Duplicate argument: --brainstorm" "duplicate brainstorm" \
  "--writing-plan --writing-plan" "Duplicate argument: --writing-plan" "duplicate writing plan" \
  "--architect --architect" "Duplicate argument: --architect" "duplicate architect" \
  "--architect --new --new" "Duplicate argument: --new" "duplicate new" \
  "--brainstorm --writing-plan" "mutually exclusive" "planning mode conflict" \
  "--new" "--new requires --architect" "orphan new" \
  "--architect --prompt" "may combine only with --new and --yolo" "architect prompt conflict" \
  "--architect --brainstorm" "may combine only with --new and --yolo" "architect brainstorm conflict" \
  "--architect --writing-plan" "may combine only with --new and --yolo" "architect writing conflict"; do
  run_plan "$args"
  assert_equal 1 "$rc" "$label status"
  assert_contains "$output" "$expected" "$label message"
done

export CLAUDE_CODE_SAFE_MODE=1
output="$(_plan_build_superpowers_preflight 2>&1)"
rc=$?
unset CLAUDE_CODE_SAFE_MODE
assert_equal 1 "$rc" "safe mode failure"
assert_contains "$output" "safe mode disables Superpowers" "safe mode guidance"

mkdir -p "$fixture_dir/bin" "$fixture_dir/home/.augment" "$fixture_dir/enhance-tmp"
print -r -- '{}' >| "$fixture_dir/home/.augment/session.json"
print -r -- '#!/bin/sh' >| "$fixture_dir/bin/script"
print -r -- 'printf "%s\n" "$@" > "$PLAN_BUILD_SCRIPT_ARGS"' >> "$fixture_dir/bin/script"
print -r -- 'if [ "$1" = -q ] && [ "$2" = -t ]; then log_file=$4; shift 4; "$@" > "$log_file"; exit $?; fi' >> "$fixture_dir/bin/script"
print -r -- 'log_file=$4; printf "Enhanced prompt: linux result\n" > "$log_file"; exit "${PLAN_BUILD_SCRIPT_STATUS:-0}"' >> "$fixture_dir/bin/script"
print -r -- '#!/bin/sh' >| "$fixture_dir/bin/auggie"
print -r -- 'printf "Enhanced prompt: mac result\n"; exit "${PLAN_BUILD_AUGGIE_STATUS:-0}"' >> "$fixture_dir/bin/auggie"
chmod +x "$fixture_dir/bin/script" "$fixture_dir/bin/auggie"

_plan_build_confirm_indexing() { return 1 }

typeset platform script_args enhance_output
trap 'print -u2 -r -- "test INT trap"' INT
typeset caller_int_trap="$(trap -p INT)"
for platform in Darwin Linux; do
  _plan_build_platform() { print -r -- "$platform" }
  : >| "$fixture_dir/script-args"
  enhance_output="$fixture_dir/enhanced-$platform"
  HOME="$fixture_dir/home" TMPDIR="$fixture_dir/enhance-tmp" \
    PATH="$fixture_dir/bin:$PATH" PLAN_BUILD_SCRIPT_ARGS="$fixture_dir/script-args" \
    _plan_build_real_enhance_prompt "raw prompt" "$enhance_output"
  rc=$?
  assert_equal 0 "$rc" "$platform script enhancement status"
  script_args="$(<"$fixture_dir/script-args")"
  if [[ "$platform" == Darwin ]]; then
    assert_contains "$script_args" $'-t\n0' "macOS script immediate flushing"
    assert_contains "$script_args" $'auggie\n--print' "macOS script direct executable dispatch"
    assert_not_contains "$script_args" $'\ncommand\n' "macOS script excludes shell builtin"
    assert_equal "mac result" "$(<"$enhance_output")" "macOS parsed enhancement"
  else
    assert_contains "$script_args" $'-f\n-O' "Linux script immediate flushing"
    assert_contains "$script_args" "-c" "Linux script command mode"
    assert_equal "linux result" "$(<"$enhance_output")" "Linux parsed enhancement"
  fi
  assert_equal 0 "$(count_matches "$fixture_dir/enhance-tmp" plan-build-auggie)" "$platform run directory cleanup"
done
assert_equal "$caller_int_trap" "$(trap -p INT)" "enhancement traps remain local to caller"
trap - INT

platform=Darwin
_plan_build_platform() { print -r -- "$platform" }
PLAN_BUILD_AUGGIE_STATUS=7 HOME="$fixture_dir/home" TMPDIR="$fixture_dir/enhance-tmp" \
  PATH="$fixture_dir/bin:$PATH" PLAN_BUILD_SCRIPT_ARGS="$fixture_dir/script-args" \
  _plan_build_real_enhance_prompt "partial prompt" "$fixture_dir/failed-enhancement" >/dev/null 2>&1
rc=$?
assert_equal 7 "$rc" "nonzero Auggie status propagated"
[[ ! -e "$fixture_dir/failed-enhancement" ]] || fail "failed Auggie output was accepted"
assert_equal 0 "$(count_matches "$fixture_dir/enhance-tmp" plan-build-auggie)" "failed run directory cleanup"

print -r -- $'noise\r\n\e[32m✨ Enhanced prompt: first\e[0m\r\nsecond\r\n🤖 tool' >| "$fixture_dir/parser.log"
_plan_build_parse_auggie_output "$fixture_dir/parser.log" "$fixture_dir/parser.out"
assert_equal $'first\nsecond' "$(<"$fixture_dir/parser.out")" "parser strips terminal output and stops at marker"
print -r -- "no enhanced prompt" >| "$fixture_dir/parser-empty.log"
_plan_build_parse_auggie_output "$fixture_dir/parser-empty.log" "$fixture_dir/parser-empty.out"
[[ ! -s "$fixture_dir/parser-empty.out" ]] || fail "parser accepted output without marker"

typeset -g enhanced_text="enhanced payload"
typeset -gi enhanced_approval=0
typeset -gi architect_preflight_result=0
typeset -gi enhancement_result=0

_plan_build_require_cli() {
  print -r -- "SEAM:cli:$1"
  return 0
}
_plan_build_superpowers_preflight() {
  print -r -- "SEAM:superpowers"
  return 0
}
_plan_build_architect_preflight() {
  print -r -- "SEAM:architect-preflight"
  return "$architect_preflight_result"
}
_plan_build_enhance_prompt() {
  print -r -- "SEAM:auggie:$1"
  print -r -- "$enhanced_text" >| "$2"
  return "$enhancement_result"
}
_plan_build_confirm_enhanced_prompt() {
  print -r -- "SEAM:enhanced-approval"
  return "$enhanced_approval"
}
_plan_build_launch_claude() {
  print -r -- "SEAM:claude"
  printf 'CLAUDE_YOLO=<%s>\nCLAUDE_PROMPT=<%s>\n' "$1" "$2"
}

run_plan "" "first line\nsecond line\nEOF\nignored line\n"
assert_equal 0 "$rc" "standard mode status"
assert_contains "$output" "Planning mode: standard" "standard planning prompt"
assert_contains "$output" $'first line\nsecond line' "multiline payload"
assert_not_contains "$output" "ignored line" "EOF terminates payload"

run_plan "--brainstorm" "build feature\nEOF\n"
assert_equal 0 "$rc" "brainstorm status"
assert_contains "$output" "Planning mode: brainstorm" "brainstorm prompt"
assert_equal "cli:claude superpowers cli:codex cli:coderabbit claude" "$(seam_events "$output")" "brainstorm preflight ordering"

run_plan "--writing-plan" "build feature\nEOF\n"
assert_equal 0 "$rc" "writing-plan status"
assert_contains "$output" "Planning mode: writing-plan" "writing-plan prompt"

enhanced_approval=0
run_plan "--prompt" "raw payload\nEOF\n"
assert_equal 0 "$rc" "prompt mode approved status"
assert_contains "$output" "enhanced payload" "enhanced prompt used"
assert_contains "$output" "Enhanced prompt approved" "enhanced approval reported"
assert_equal "cli:claude cli:codex cli:coderabbit cli:auggie cli:script cli:perl auggie:raw payload enhanced-approval claude" "$(seam_events "$output")" "prompt seams ordering"

enhancement_result=9
run_plan "--prompt" "failed child\nEOF\n"
assert_equal 9 "$rc" "prompt child failure status propagated"
assert_not_contains "$output" "enhanced-approval" "failed enhancement is never parsed or approved"
assert_not_contains "$output" "SEAM:claude" "failed enhancement prevents launch"
assert_equal 0 "$(count_matches "$TMPDIR" plan-build-enhanced)" "enhanced temporary file cleanup"
enhancement_result=0

run_plan "--prompt --brainstorm" "raw combination\nEOF\n"
assert_equal 0 "$rc" "prompt brainstorm status"
assert_contains "$output" "Planning mode: brainstorm" "prompt brainstorm planning"

enhanced_approval=1
run_plan "--prompt" "declined\nEOF\n"
assert_equal 0 "$rc" "prompt rejection exits cleanly"
assert_contains "$output" "not approved" "prompt rejection message"
assert_equal "cli:claude cli:codex cli:coderabbit cli:auggie cli:script cli:perl auggie:declined enhanced-approval" "$(seam_events "$output")" "prompt rejection prevents launch"
enhanced_approval=0

run_plan "--architect" "design feature\nEOF\n"
assert_equal 0 "$rc" "architect safe-resume status"
assert_contains "$output" "Start mode: safe-resume-detection" "architect safe-resume mode"
assert_contains "$output" "documentation-first architect/orchestrator role" "architect role boundary"
assert_equal "architect-preflight claude" "$(seam_events "$output")" "architect preflight before launch"

run_plan "--architect --new" "fresh design\nEOF\n"
assert_equal 0 "$rc" "architect new status"
assert_contains "$output" "Start mode: archive-and-start-new" "architect new mode"

run_plan "--architect --yolo" "fast design\nEOF\n"
assert_equal 0 "$rc" "architect yolo status"
assert_contains "$output" "CLAUDE_YOLO=<1>" "architect yolo reaches launch seam"
assert_contains "$output" "including every gate" "architect yolo retains gates"

architect_preflight_result=1
run_plan "--architect" "must not be read\nEOF\n"
assert_equal 1 "$rc" "architect preflight failure status"
assert_not_contains "$output" "Reading payload" "architect preflight precedes payload"
assert_equal "architect-preflight" "$(seam_events "$output")" "architect failure stops processing"
architect_preflight_result=0

run_plan "" "EOF\n"
assert_equal 1 "$rc" "empty payload status"
assert_contains "$output" "Payload was empty" "empty payload message"

print -r -- '#!/bin/sh' >| "$fixture_dir/bin/claude"
print -r -- 'printf "REAL_CLAUDE:"; printf " <%s>" "$@"; printf "\n"' >> "$fixture_dir/bin/claude"
chmod +x "$fixture_dir/bin/claude"
output="$(PATH="$fixture_dir/bin:$PATH" _plan_build_real_launch_claude 1 "payload")"
assert_contains "$output" "<--dangerously-skip-permissions>" "yolo translates to real Claude argument"
assert_not_contains "$output" "<--yolo>" "yolo alias not forwarded"

if (( failures )); then
  print -u2 -r -- "FAIL: $failures plan_build test(s)"
  exit 1
fi

print -r -- "PASS: plan_build tests"
