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

LIB="$(cd "$(dirname "$0")" && pwd)/backlog.sh"
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"; }
run()  { bash "$LIB" "$@"; }

if ! command -v jq >/dev/null 2>&1; then
  echo "ERROR: jq required for tests but not found" >&2
  exit 1
fi

echo "backlog.sh tests:"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
record='{"v":"backlog/v1","task":"t8","status":"pending","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z"}'
if run append "$jsonl" "$record" && [[ -f "$jsonl" ]] && [[ $(wc -l < "$jsonl") -eq 1 ]] \
    && [[ "$(sed -n '1p' "$jsonl")" == "$record" ]]; then
  ok "append valid record"
else
  bad "append valid record" "unexpected result"
fi
rm -rf "$tmpdir"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
if run append "$jsonl" '{bad json' >/dev/null 2>&1; then
  bad "append invalid JSON" "expected failure"
else
  rc=$?
  [[ $rc -eq 3 && ! -f "$jsonl" ]] && ok "append invalid JSON" || bad "append invalid JSON" "exit=$rc"
fi
rm -rf "$tmpdir"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
printf '%s\n' '{"v":"backlog/v1","task":"t8","status":"pending","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z"}' > "$jsonl"
if run append "$jsonl" '{"v":"backlog/v1","task":"t8","status":"queued","title":"Duplicate","ts":"2026-07-02T01:03:03Z"}' >/dev/null 2>&1; then
  bad "append duplicate task" "expected failure"
else
  rc=$?
  lines=$(wc -l < "$jsonl")
  [[ $rc -eq 3 && "$lines" -eq 1 ]] && ok "append duplicate task" || bad "append duplicate task" "exit=$rc lines=$lines"
fi
rm -rf "$tmpdir"

if run append >/dev/null 2>&1; then
  bad "append bad args" "expected failure"
else
  rc=$?
  [[ $rc -eq 2 ]] && ok "append bad args" || bad "append bad args" "exit=$rc"
fi

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
cat > "$jsonl" <<EOF
{"v":"backlog/v1","task":"t8","status":"pending","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z","notes":["first"]}
{"v":"backlog/v1","task":"t9","status":"done","title":"Other task","ts":"2026-07-02T01:05:03Z"}
EOF
before_t8=$(jq -c 'select(.task=="t8")' "$jsonl")
before_t9=$(jq -c 'select(.task=="t9")' "$jsonl")
if run set-status "$jsonl" t8 in_progress; then
  after_t8=$(jq -c 'select(.task=="t8")' "$jsonl")
  after_t9=$(jq -c 'select(.task=="t9")' "$jsonl")
  status=$(printf '%s' "$after_t8" | jq -r '.status')
  title=$(printf '%s' "$after_t8" | jq -r '.title')
  note=$(printf '%s' "$after_t8" | jq -r '.notes[0]')
  ts=$(printf '%s' "$after_t8" | jq -r '.ts')
  if [[ "$status" == "in_progress" && "$title" == "Build backlog helper" && "$note" == "first" && "$ts" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T ]]; then
    ok "set-status updates matching record and refreshes ts"
  else
    bad "set-status updates matching record and refreshes ts" "record=$after_t8"
  fi
  [[ "$after_t9" == "$before_t9" ]] && ok "set-status preserves non-target records" || bad "set-status preserves non-target records" "before=$before_t9 after=$after_t9"
  [[ "$(printf '%s' "$before_t8" | jq -r '.status')" == "pending" ]] && ok "set-status test starts from pending state" || bad "set-status test starts from pending state" "before=$before_t8"
else
  bad "set-status updates matching record and refreshes ts" "command failed"
fi
rm -rf "$tmpdir"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
printf '%s\n' '{"v":"backlog/v1","task":"t8","status":"pending","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z"}' > "$jsonl"
if run set-status "$jsonl" missing done >/dev/null 2>&1; then
  bad "set-status missing task" "expected failure"
else
  rc=$?
  [[ $rc -eq 3 ]] && ok "set-status missing task" || bad "set-status missing task" "exit=$rc"
fi
rm -rf "$tmpdir"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
cat > "$jsonl" <<EOF
{"v":"backlog/v1","task":"dup","status":"pending","title":"one","ts":"2026-07-02T01:02:03Z"}
{"v":"backlog/v1","task":"dup","status":"pending","title":"two","ts":"2026-07-02T01:03:03Z"}
EOF
if run set-status "$jsonl" dup done >/dev/null 2>&1; then
  bad "set-status duplicate task fails closed" "expected failure"
else
  rc=$?
  first=$(sed -n '1p' "$jsonl")
  second=$(sed -n '2p' "$jsonl")
  [[ $rc -eq 3 && "$first" == '{"v":"backlog/v1","task":"dup","status":"pending","title":"one","ts":"2026-07-02T01:02:03Z"}' && "$second" == '{"v":"backlog/v1","task":"dup","status":"pending","title":"two","ts":"2026-07-02T01:03:03Z"}' ]] \
    && ok "set-status duplicate task fails closed" || bad "set-status duplicate task fails closed" "exit=$rc"
fi
rm -rf "$tmpdir"

if run set-status >/dev/null 2>&1; then
  bad "set-status bad args" "expected failure"
else
  rc=$?
  [[ $rc -eq 2 ]] && ok "set-status bad args" || bad "set-status bad args" "exit=$rc"
fi

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
cat > "$jsonl" <<EOF
{"v":"backlog/v1","task":"t8","status":"pending","priority":"low","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z"}
{"v":"backlog/v1","task":"t9","status":"done","priority":"medium","title":"Other task","ts":"2026-07-02T01:05:03Z"}
EOF
if run set-priority "$jsonl" t8 high; then
  after_t8=$(jq -c 'select(.task=="t8")' "$jsonl")
  after_t9=$(jq -c 'select(.task=="t9")' "$jsonl")
  priority=$(printf '%s' "$after_t8" | jq -r '.priority')
  if [[ "$priority" == "high" && "$after_t9" == '{"v":"backlog/v1","task":"t9","status":"done","priority":"medium","title":"Other task","ts":"2026-07-02T01:05:03Z"}' ]]; then
    ok "set-priority updates matching record only"
  else
    bad "set-priority updates matching record only" "t8=$after_t8 t9=$after_t9"
  fi
else
  bad "set-priority updates matching record only" "command failed"
fi
rm -rf "$tmpdir"

tmpdir=$(mktemp -d)
jsonl="$tmpdir/backlog.jsonl"
printf '%s\n' '{"v":"backlog/v1","task":"t8","status":"pending","title":"Build backlog helper","ts":"2026-07-02T01:02:03Z"}' > "$jsonl"
if run set-priority "$jsonl" t8 urgent >/dev/null 2>&1; then
  bad "set-priority invalid priority" "expected failure"
else
  rc=$?
  [[ $rc -eq 3 ]] && ok "set-priority invalid priority" || bad "set-priority invalid priority" "exit=$rc"
fi
rm -rf "$tmpdir"

if run set-priority >/dev/null 2>&1; then
  bad "set-priority bad args" "expected failure"
else
  rc=$?
  [[ $rc -eq 2 ]] && ok "set-priority bad args" || bad "set-priority bad args" "exit=$rc"
fi

echo
echo "PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]]
