#!/usr/bin/env bash
#
# research-loop.sh
#
# Starts an interactive Claude Code session:
#   - first run: 2 hours 30 minutes after this script starts
#   - later runs: every 5 hours
#   - each session is SIGKILLed 5 minutes before the next window
#   - stops when no unchecked Markdown checkboxes remain
#
set -euo pipefail

REPO="/Users/ca_ai/Desktop/Projects/36.RealEstateAI/1.Code"

PLAN="workflow/research/1.initial-architecture-research/3.12072026 - Architecture Research Plan (execute with goal).md"

PROMPT='/goal complete "workflow/research/1.initial-architecture-research/3.12072026 - Architecture Research Plan (execute with goal).md" — resume from the first unchecked checkbox in §7, verifying against files on disk: tick boxes whose output file already exists; redo agents whose output is missing; stop only when all checkboxes are complete'

INITIAL_DELAY_SECONDS=$(( 30 * 60))
#INITIAL_DELAY_SECONDS=$((4 * 60 * 60 +  30 * 60))

# Claude subscription session windows reset every five hours.
WINDOW_SECONDS=$((5 * 60 * 60))

# Kill the old interactive session shortly before launching the next one.
KILL_BUFFER_SECONDS=$((5 * 60))

cd "$REPO"

if [[ ! -f "$PLAN" ]]; then
    echo "ERROR: plan not found:"
    echo "  $REPO/$PLAN"
    exit 1
fi

if ! command -v claude >/dev/null 2>&1; then
    echo "ERROR: claude command not found."
    exit 1
fi

# GNU timeout is named gtimeout when installed through Homebrew coreutils.
if command -v timeout >/dev/null 2>&1; then
    TIMEOUT_COMMAND="timeout"
elif command -v gtimeout >/dev/null 2>&1; then
    TIMEOUT_COMMAND="gtimeout"
else
    echo "ERROR: timeout/gtimeout not found."
    echo "On macOS: brew install coreutils"
    exit 1
fi

# Prevent accidentally using paid API billing instead of the Claude subscription.
if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
    echo "ERROR: ANTHROPIC_API_KEY is set."
    echo "Run: unset ANTHROPIC_API_KEY"
    echo "Then restart this script."
    exit 1
fi

format_epoch() {
    local timestamp="$1"

    # macOS date
    if date -r "$timestamp" "+%Y-%m-%d %H:%M:%S %Z" 2>/dev/null; then
        return
    fi

    # GNU/Linux date
    date -d "@$timestamp" "+%Y-%m-%d %H:%M:%S %Z"
}

has_unchecked_work() {
    grep -q -- '- \[ \]' "$PLAN"
}

interrupt() {
    echo
    echo "research-loop: interrupted."
    exit 130
}

trap interrupt INT TERM

next_start=$(( $(date +%s) + INITIAL_DELAY_SECONDS ))
iteration=0

echo "research-loop: repository: $REPO"
echo "research-loop: first run:  $(format_epoch "$next_start")"
echo "research-loop: interval:   5 hours"
echo "research-loop: Ctrl-C stops the loop."

while has_unchecked_work; do
    now=$(date +%s)

    # If the computer was asleep and an entire slot was missed,
    # advance to the next usable scheduled window.
    while (( now >= next_start + WINDOW_SECONDS - KILL_BUFFER_SECONDS )); do
        echo "research-loop: missed slot at $(format_epoch "$next_start"); skipping."
        next_start=$((next_start + WINDOW_SECONDS))
    done

    now=$(date +%s)

    if (( now < next_start )); then
        echo
        echo "research-loop: next run at $(format_epoch "$next_start")"
        sleep $((next_start - now))
    fi

    # Re-check after sleeping in case the plan was completed elsewhere.
    if ! has_unchecked_work; then
        break
    fi

    iteration=$((iteration + 1))
    following_start=$((next_start + WINDOW_SECONDS))

    # Cap this run relative to the fixed next-window boundary.
    run_timeout=$((following_start - $(date +%s) - KILL_BUFFER_SECONDS))

    if (( run_timeout <= 0 )); then
        next_start="$following_start"
        continue
    fi

    echo
    echo "============================================================"
    echo "research-loop: iteration $iteration"
    echo "  started:      $(date '+%Y-%m-%d %H:%M:%S %Z')"
    echo "  hard timeout: ${run_timeout}s"
    echo "  next window:  $(format_epoch "$following_start")"
    echo "============================================================"

    started_at=$SECONDS

    set +e
    "$TIMEOUT_COMMAND" \
        --foreground \
        --signal=KILL \
        "$run_timeout" \
        claude \
            --dangerously-skip-permissions \
            --verbose \
            "$PROMPT"

    exit_code=$?
    set -e

    elapsed=$((SECONDS - started_at))

    echo
    echo "research-loop: Claude ended:"
    echo "  exit code: $exit_code"
    echo "  elapsed:   ${elapsed}s"

    case "$exit_code" in
        130)
            echo "research-loop: interrupted."
            exit 130
            ;;
        137)
            echo "research-loop: session reached its hard timeout and was SIGKILLed."
            ;;
        *)
            echo "research-loop: session exited normally or returned an error."
            ;;
    esac

    if ! has_unchecked_work; then
        break
    fi

    # Wait for the next fixed five-hour window even if Claude exited early.
    next_start="$following_start"
done

echo
echo "research-loop: all Markdown checkboxes are complete."