#!/usr/bin/env bash
# wm-gen: Generate and dispatch a task from a template + description.
#
# Usage:
#   wm-gen <template> <description>        # dispatch immediately
#   wm-gen <template> <description> --name ID  # dispatch with tracking ID
#   wm-gen --list                           # list available templates
#   echo "description" | wm-gen <template>  # description from stdin
#
# Templates:
#   1  Signature XEvent*→WMEvent*
#   2  Eliminate _x11_raw
#   3  Xlib→wm_backend vtable
#   4  Guard X11 block (if scr->display)
#   5  Split into _x11/_wl pair
#   6  Xlib drawing→render backend
#   7  Remove #ifdef guard
#   8  WPrefs Xlib→WINGs API
#   9  Verification
#
# Options:
#   --name ID     Tracking name (default: gen-<timestamp>)
#   --dry-run     Print the prompt, don't dispatch
#   --backend B   Override backend
#   --model M     Override model
#   --bg          Background dispatch
#   --keep        Keep session after completion
#
# Examples:
#   wm-gen 3 "Replace XClearArea at wrlib/context.c:730 with wm_backend->window_clear_area"
#   wm-gen 4 "Guard X11 init block at WINGs/widgets.c:637-739"
#   wm-gen 2 "Eliminate _x11_raw at src/framewin.c:1165" --name fix-framewin

set -euo pipefail

ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
TOOLS="$ROOT/tools/wm-port"
MOUNT="${OLLIE:-$HOME/mnt/ollie}"
LOG_DIR="$TOOLS/logs"

source "$TOOLS/task-map.sh"
mkdir -p "$LOG_DIR"

die() { printf 'wm-gen: %s\n' "$*" >&2; exit 1; }

if [ "${1:-}" = "--list" ]; then
    for t in 1 2 3 4 5 6 7 8 9; do
        printf '  %s  %s\n' "$t" "${TEMPLATE_NAME[$t]}"
    done
    exit 0
fi

# Defaults
backend="openrouter"
model="anthropic/claude-sonnet-4"
dry_run=0
keep=0
bg=0
name=""
tnum=""
desc_args=()

while [ $# -gt 0 ]; do
    case "$1" in
        --name)      name="$2"; shift ;;
        --dry-run)   dry_run=1 ;;
        --backend)   backend="$2"; shift ;;
        --model)     model="$2"; shift ;;
        --bg)        bg=1 ;;
        --keep)      keep=1 ;;
        --help|-h)   sed -n '2,/^$/{ s/^# //; s/^#//; p; }' "$0"; exit 0 ;;
        -*)          die "unknown flag: $1" ;;
        *)           if [ -z "$tnum" ] && [[ "$1" =~ ^[1-9]$ ]]; then
                         tnum="$1"
                     else
                         desc_args+=("$1")
                     fi
                     ;;
    esac
    shift
done

[ -n "$tnum" ] || die "template number required (1-9). Use --list to see templates."
[ -n "${TEMPLATE_NAME[$tnum]:-}" ] || die "invalid template number: $tnum"

# Read description from args or stdin
if [ ${#desc_args[@]} -gt 0 ] && ! [ -t 0 ]; then
    description="${desc_args[*]}"$'\n'"$(cat)"
elif [ ${#desc_args[@]} -gt 0 ]; then
    description="${desc_args[*]}"
elif ! [ -t 0 ]; then
    description=$(cat)
else
    die "description required: pass as arguments or pipe via stdin"
fi

[ -n "$description" ] || die "empty description"

name="${name:-gen-$(date +%s)}"

# Extract the template procedure
extract_template() {
    local t="$1"
    local prompts="$ROOT/ACTION_PLAN_PROMPTS.md"
    awk -v tnum="$t" '
        BEGIN { found=0; in_code=0 }
        /^## Template / {
            if (found && !in_code) exit
            if ($0 ~ "Template " tnum ":" || $0 ~ "Template " tnum " ") {
                found=1
                next
            }
        }
        /^## Template [0-9]/ { if (found) exit }
        /^---$/ { if (found && !in_code) exit }
        found { print }
    ' "$prompts"
}

extract_reference_tables() {
    local prompts="$ROOT/ACTION_PLAN_PROMPTS.md"
    awk '
        /^## Reference Tables/,/^## Template 1/ {
            if (/^## Template 1/) exit
            print
        }
    ' "$prompts"
}

template=$(extract_template "$tnum")
ref_tables=$(extract_reference_tables)
tname="${TEMPLATE_NAME[$tnum]}"

prompt=$(cat <<PROMPT
You are executing a mechanical Wayland porting task for WindowMaker.

# Task: $name ($tname)

## What to do

$description

## Procedure (Template $tnum: $tname)

$template

$ref_tables

## Important Rules

1. Work in the git repository at $ROOT. Create a git branch named "port/$name" before making changes.
2. Make exactly the changes described. No more, no less.
3. After making changes, verify with the grep commands in the template.
4. Attempt to compile with: cd $ROOT && make -j\$(nproc) 2>&1 | tail -30
5. If compilation fails, fix the errors. If you cannot fix them, revert and report.
6. If you hit a STOP condition (missing vtable slot, missing API), revert changes and report exactly what is missing.
7. When done, run: git add -A && git diff --cached --stat
8. Report the final status as one of:
   - DONE: task completed, compiles clean
   - STOP: blocked on <reason>
   - FAIL: could not complete because <reason>

Line numbers may have drifted. Use grep to find current line numbers before editing.
PROMPT
)

if [ "$dry_run" -eq 1 ]; then
    echo "════════════════════════════════════════"
    echo "TASK: $name  (Template $tnum: $tname)"
    echo "════════════════════════════════════════"
    echo "$prompt"
    exit 0
fi

session_name="wm-port-${name}"
session_path="$MOUNT/s/$session_name"
flags=(
    -name "$session_name"
    -cwd "$ROOT"
    -agent coding
    -backend "$backend"
    -model "$model"
    -keep
)
[ "$bg" -eq 1 ] && flags+=(-bg)

printf '\033[1;36m▶ Dispatching %s\033[0m (T%s: %s)\n' "$name" "$tnum" "$tname" >&2

if [ "$bg" -eq 1 ]; then
    sp=$(printf '%s' "$prompt" | "$MOUNT/s/b" "${flags[@]}")
    printf '%s\t%s\n' "$name" "$sp"
    printf '\033[1;33m  → %s\033[0m\n' "$sp" >&2
else
    result=$(printf '%s' "$prompt" | "$MOUNT/s/b" "${flags[@]}" 2>/dev/null) || true
    printf '%s\n' "$result" > "$LOG_DIR/${name}.log"

    if [ -z "$result" ] || echo "$result" | head -1 | grep -q '^user:'; then
        printf '\033[1;31m✗ %s: FAIL (agent produced no response)\033[0m\n' "$name" >&2
        printf '  Session: %s\n' "$session_path" >&2
    elif echo "$result" | grep -qiE '\*\*DONE\*\*|^DONE:|^DONE\b|DONE: task completed'; then
        printf '\033[1;32m✓ %s: DONE\033[0m\n' "$name" >&2
        if [ "$keep" -eq 0 ]; then
            echo kill > "$session_path/ctl" 2>/dev/null || true
        else
            printf '  Session: %s\n' "$session_path" >&2
        fi
    elif echo "$result" | grep -qiE '\*\*STOP\*\*|^STOP:|^STOP\b'; then
        printf '\033[1;33m⚠ %s: STOP\033[0m\n' "$name" >&2
        echo "$result" | grep -iE 'STOP' | head -3 | sed 's/^/  /' >&2
        printf '  Session: %s\n' "$session_path" >&2
    elif echo "$result" | grep -qiE '\*\*FAIL\*\*|^FAIL:|^FAIL\b'; then
        printf '\033[1;31m✗ %s: FAIL\033[0m\n' "$name" >&2
        echo "$result" | grep -iE 'FAIL' | head -3 | sed 's/^/  /' >&2
        printf '  Session: %s\n' "$session_path" >&2
    else
        printf '\033[1;35m? %s: status unclear\033[0m\n' "$name" >&2
        echo "$result" | grep -v '^$' | tail -5 | sed 's/^/  /' >&2
        printf '  Session: %s\n' "$session_path" >&2
    fi

    printf '  Log: %s\n' "$LOG_DIR/${name}.log" >&2
fi
