#!/usr/bin/env bash
# Builds the karr fleet sandbox under ex/ — sample boards, .karr files, a
# karr-foundation config, demo agents and a chain in the hub — so the examples
# in the README (and in docs/) can be run by hand against a real setup.
#
# Usage:
#   ./ex/setup.sh          create the sandbox (idempotent: existing pieces are
#                          left alone and reported)
#   ./ex/setup.sh --reset  wipe the generated state and rebuild from scratch
#
# The generated state (the sample repos, their boards and the config file) is
# machine-local and never committed — git refs cannot be committed, so the
# boards are built here at run time. Only this script and ex/bin, ex/scripts
# and ex/README.md live in the repository.
set -euo pipefail

EX="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$EX/.." && pwd)"

if [ "${1:-}" = "--reset" ]; then
  rm -rf "$EX/webapp" "$EX/docs-site" "$EX/fleet-hub" "$EX/config.yml"
  echo "ex/: wiped generated state"
fi

# --- how we call karr --------------------------------------------------------
# Default: the repo checkout (perl -Ilib bin/karr). Set KARR_BIN to point at an
# installed binary instead, e.g.  KARR_BIN="$(command -v karr)".
karr() {
  if [ -n "${KARR_BIN:-}" ]; then "$KARR_BIN" "$@"
  else perl -I"$REPO_ROOT/lib" "$REPO_ROOT/bin/karr" "$@"; fi
}
foundation() {
  if [ -n "${KARR_BIN:-}" ]; then "${KARR_BIN%karr}karr-foundation" "$@"
  else perl -I"$REPO_ROOT/lib" "$REPO_ROOT/bin/karr-foundation" "$@"; fi
}

make_repo() {  # make_repo NAME
  local name="$1" dir="$EX/$1"
  if [ -d "$dir/.git" ]; then
    echo "ex/$name: already exists (leave as is; --reset to rebuild)"
    return 0
  fi
  mkdir -p "$dir"
  git -C "$dir" init -q -b main
  git -C "$dir" config user.email demo@example.com
  git -C "$dir" config user.name "Demo"
  karr --dir "$dir" init --name "$name" >/dev/null
  # karr-foundation per-repo state files are machine-local (docs, section 2):
  # init only ignores the materialized file view, so add them by hand.
  {
    printf '\n# karr-foundation per-repo state — machine-local, never commit\n'
    printf '.karr\n.karr.state\n.karr.lock\n.karr.log\n'
  } >> "$dir/.gitignore"
  git -C "$dir" add .gitignore
  git -C "$dir" commit -q -m "bootstrap $name"
  echo "ex/$name: board created"
}

# --- webapp ------------------------------------------------------------------
make_repo webapp
if [ -d "$EX/webapp" ] && ! karr --dir "$EX/webapp" show 1 >/dev/null 2>&1; then
  W() { karr --dir "$EX/webapp" "$@"; }
  W create --title "Fix login bug" --priority high --body "Session cookie is dropped on the second request. Reproduce on staging with two tabs." >/dev/null
  W move 1 in-progress --claim agent-fox
  W create --title "Rate limit the API" --priority medium --depends_on 1 >/dev/null
  W create --title "Publish release notes" --priority low >/dev/null
  W move 3 review --claim agent-fox
  W create --title "Upgrade TLS on staging" --priority critical >/dev/null
  W edit 4 --block "waiting for the certificate from ops" >/dev/null
  W create --title "Write integration tests for checkout" --priority high >/dev/null
  W create --title "Deploy the 0.6 release" --priority low --needs docs-site#1 >/dev/null
  echo "ex/webapp: sample cards created"
fi

# --- docs-site ---------------------------------------------------------------
make_repo docs-site
if [ -d "$EX/docs-site" ] && ! karr --dir "$EX/docs-site" show 1 >/dev/null 2>&1; then
  D() { karr --dir "$EX/docs-site" "$@"; }
  D create --title "Update the installation quickstart" --priority medium >/dev/null
  D create --title "Rewrite the deployment section" --priority low >/dev/null
  D move 2 in-progress --claim agent-fox
  echo "ex/docs-site: sample cards created"
fi

# --- fleet-hub ---------------------------------------------------------------
make_repo fleet-hub

# --- .karr files -------------------------------------------------------------
if [ ! -f "$EX/webapp/.karr" ]; then
  cat > "$EX/webapp/.karr" <<EOF
mode: ticket
agent: demo
prompt: "You are a demo agent. Work the assigned card, move it to review and hand it off under your own claim."
max_attempts: 2
EOF
fi
if [ ! -f "$EX/docs-site/.karr" ]; then
  cat > "$EX/docs-site/.karr" <<EOF
mode: drain
command: $EX/bin/drain-agent.sh
prompt: "You are a demo agent. Pick the next assignable card and work it all the way to done, so the drain run terminates."
max_attempts: 2
EOF
fi

# --- karr-foundation config --------------------------------------------------
cat > "$EX/config.yml" <<EOF
# Generated by ex/setup.sh — points at the sandbox repos with absolute paths.
dirs:
  - $EX/webapp
  - $EX/docs-site
hub: $EX/fleet-hub
concurrent: 1
agents:
  demo:
    command: $EX/bin/fake-agent.sh
    kind: shell
    probe_every: 10m
    description: >-
      Demo agent for the ex/ sandbox. Moves the assigned card to review and
      hands it off. Swap the .karr command for lazy-agent.sh or
      failing-agent.sh to see stall/autoblock and cooldown.
default_agent: demo
EOF
echo "ex/config.yml: written"

# --- the chain ---------------------------------------------------------------
perl -I"$REPO_ROOT/lib" "$EX/scripts/write-chain.pl" "$EX/fleet-hub"
echo
echo "Sandbox ready. The walkthrough is $EX/README.md. Try:"
echo "  perl -I$REPO_ROOT/lib $REPO_ROOT/bin/karr --dir $EX/webapp board"
echo "  perl -I$REPO_ROOT/lib $REPO_ROOT/bin/karr-foundation --config $EX/config.yml --status"
