#!/usr/bin/env bash
# Buildbox-side setup for ONE resident seat (S2/S3): a long-lived rootless podman container the
# owner attaches to interactively over tmux, as opposed to seat-run.sh's one-shot --rm dispatch.
# Invoked through the SAME remote-build transport as a dispatch (`rb-<jobId>.service`), but this
# script only ARRANGES the container and the host tmux session, then exits — the container and the
# tmux server both daemonize independently of this transient unit, so they outlive it.
#
# Idempotent: safe to run again against the same --slug. A running container/session is left
# alone; a stopped container is restarted; a missing one is created.
set -uo pipefail

fail3() { printf '{"ok":false,"detail":"seat-resident-run: %s"}\n' "$1" >&2; exit 3; }

SLUG="" REPO_ROOT="" WORKSPACE_REL="." IMAGE="" MEMORY="" CPUS="" PIDS="" CGROUP_PARENT="" TMPFS_SIZE=""
GIT_NAME="" GIT_EMAIL="" MAX_RESIDENTS=""
while [[ $# -gt 0 ]]; do
  case "$1" in
    --slug)          SLUG="${2:-}";          shift 2;;
    --repo-root)     REPO_ROOT="${2:-}";     shift 2;;
    --workspace-rel) WORKSPACE_REL="${2:-}"; shift 2;;
    --image)         IMAGE="${2:-}";         shift 2;;
    --memory)        MEMORY="${2:-}";        shift 2;;
    --cpus)          CPUS="${2:-}";          shift 2;;
    --pids)          PIDS="${2:-}";          shift 2;;
    --cgroup-parent) CGROUP_PARENT="${2:-}"; shift 2;;
    --tmpfs-size)    TMPFS_SIZE="${2:-}";    shift 2;;
    --git-name)      GIT_NAME="${2:-}";      shift 2;;
    --git-email)     GIT_EMAIL="${2:-}";     shift 2;;
    --max-residents) MAX_RESIDENTS="${2:-}"; shift 2;;
    *) printf '{"ok":false,"detail":"seat-resident-run: unknown arg %s"}\n' "$1" >&2; exit 2;;
  esac
done

[[ -n "$SLUG" && -n "$REPO_ROOT" && -n "$IMAGE" ]] \
  || { printf '{"ok":false,"detail":"seat-resident-run: missing required arg"}\n' >&2; exit 2; }
[[ "$SLUG" =~ ^[a-zA-Z0-9_-]+$ ]] || fail3 "--slug must be [a-zA-Z0-9_-]+"

# Distinct prefix from harness-seat-*: seat-run.sh's admission gate counts that name filter
# toward its 3-seat dispatch cap, and seat-reconcile.sh reaps and rc=124-finalizes every
# harness-seat-* container at boot as a crashed one-shot job. A resident container under that
# prefix would burn a permanent dispatch slot and get killed-and-reported-as-crashed on the next
# reboot pass. This prefix is invisible to both.
CONTAINER="harness-resident-$SLUG"
TMUX_SESSION="resident-$SLUG"

export PATH="$HOME/.local/bin:$PATH"
command -v podman >/dev/null 2>&1 || fail3 "podman not on PATH"
command -v tmux >/dev/null 2>&1 || fail3 "tmux not on PATH"
[[ -d "$REPO_ROOT" ]] || fail3 "repo mirror missing: $REPO_ROOT"
SEAT_SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUNDLE_ROOT="$(cd "$SEAT_SOURCE_DIR/.." && pwd)"
[[ "$BUNDLE_ROOT" == "$REPO_ROOT/"* ]] || fail3 "seat bundle is outside the repo mirror"
BUNDLE_REL="${BUNDLE_ROOT#"$REPO_ROOT/"}"
SHELL_ABS="$SEAT_SOURCE_DIR/seat-resident-shell.sh"
[[ -f "$SHELL_ABS" ]] || fail3 "seat-resident-shell.sh not in seat bundle"
[[ -d "$REPO_ROOT/$WORKSPACE_REL" ]] || fail3 "workspace not in mirror: $WORKSPACE_REL"

CREDENTIALS_MANIFEST="$SEAT_SOURCE_DIR/credentials.json"
[[ -f "$CREDENTIALS_MANIFEST" ]] || fail3 "credential manifest not in seat bundle: seat/credentials.json"
command -v jq >/dev/null || fail3 "jq is not installed on $(hostname) — the credential manifest cannot be read"
while IFS= read -r cred_home; do
  [[ -n "$cred_home" && ! -f "$HOME/$cred_home" ]] \
    && fail3 "claude credential absent on $(hostname): ~/$cred_home — the workstation converges it on the next dispatch; nothing started"
done < <(jq -r '.items[] | select((.required_by // []) | index("claude.sh")) | .home' "$CREDENTIALS_MANIFEST")

podman image exists "$IMAGE" \
  || fail3 "image $IMAGE absent — build it first: modules/harness/seat/build-image.sh $(hostname)"
podman run --rm --entrypoint /bin/sh "$IMAGE" -c \
  'test "$(command -v git)" = /usr/local/bin/git && git --deny-gate-selftest' >/dev/null \
  || fail3 "image $IMAGE cannot prove the git deny gate; nothing started"

# Every dispatch re-arms boot recovery; a resident container is not covered by it (deliberately,
# see the prefix note above), but the box's ONE-SHOT seats still need it, and this is a path every
# box that runs a resident session also crosses.
bash "$SEAT_SOURCE_DIR/seat-reconcile.sh" install "$SEAT_SOURCE_DIR" \
  || printf 'seat-resident-run: could not arm the boot reconciler on %s\n' "$(hostname)" >&2

if [[ -n "$MAX_RESIDENTS" ]]; then
  mkdir -p "$HOME/.rb/residents"
  exec {ADMIT_FD}>"$HOME/.rb/residents/.admission.lock" || fail3 "resident admission lock not creatable"
  flock -w 30 "$ADMIT_FD" || fail3 "resident admission lock held 30s on $(hostname) — podman may be wedged"
  RUNNING="$(podman ps -a --filter 'name=harness-resident-' --format '{{.Names}}' 2>/dev/null | grep -vx "$CONTAINER" | grep -c . || true)"
  [[ "$RUNNING" -lt "$MAX_RESIDENTS" ]] \
    || { exec {ADMIT_FD}>&-; fail3 "$(hostname) already runs $RUNNING/$MAX_RESIDENTS resident session(s) other than $SLUG — refused, nothing started"; }
fi

MOUNTS=(-v "$REPO_ROOT:/w:rw")
ALTERNATES="$REPO_ROOT/.git/objects/info/alternates"
if [[ -f "$ALTERNATES" ]]; then
  while IFS= read -r alt; do
    [[ -n "$alt" && -d "$alt" ]] || continue
    MOUNTS+=(-v "$alt:$alt:ro")
  done < "$ALTERNATES"
fi
seed_ro() { [[ -f "$1" ]] && MOUNTS+=(-v "$1:$2:ro"); }
while IFS=$'\t' read -r cred_home cred_seed; do
  [[ -n "$cred_home" ]] && seed_ro "$HOME/$cred_home" "$cred_seed"
done < <(jq -r '.items[] | [.home, .seed] | @tsv' "$CREDENTIALS_MANIFEST")

status() { podman inspect "$CONTAINER" --format '{{.State.Status}}' 2>/dev/null; }
CUR_STATUS="$(status)"

if [[ -z "$CUR_STATUS" ]]; then
  RUN_ARGS=(
    podman run -d --name "$CONTAINER"
    --memory "$MEMORY" --memory-swap "$MEMORY" --cpus "$CPUS" --pids-limit "$PIDS"
    --read-only --read-only-tmpfs=false
    --tmpfs "/tmp:rw,exec,mode=1777,size=$TMPFS_SIZE"
    --tmpfs "/run:rw,mode=0755,size=16m"
    --tmpfs "/seat-home:rw,exec,mode=0700,size=$TMPFS_SIZE"
    "${MOUNTS[@]}"
    --workdir /w
    --cap-drop=ALL --security-opt no-new-privileges
    --entrypoint bash
    --env HARNESS_SEAT_CONTAINER=1
    --env "SANDBOX_TOOLGAP_FILE=/w/.harness-seat/resident-$SLUG-git-denies.jsonl"
    --env "HARNESS_SEAT_CREDENTIALS_MANIFEST=/w/$BUNDLE_REL/seat/credentials.json"
  )
  [[ -n "$GIT_NAME" ]]  && RUN_ARGS+=(--env "GIT_AUTHOR_NAME=$GIT_NAME"   --env "GIT_COMMITTER_NAME=$GIT_NAME")
  [[ -n "$GIT_EMAIL" ]] && RUN_ARGS+=(--env "GIT_AUTHOR_EMAIL=$GIT_EMAIL" --env "GIT_COMMITTER_EMAIL=$GIT_EMAIL")
  [[ -n "$CGROUP_PARENT" ]] && RUN_ARGS+=(--cgroup-parent "$CGROUP_PARENT")
  # -c and NOT --rm: this container is meant to survive an owner detach for weeks. `sleep infinity`
  # is the parked main process; every real command reaches it through `podman exec`.
  RUN_ARGS+=("$IMAGE" -c 'exec sleep infinity')
  printf '=== seat-resident-run: creating %s\n' "$CONTAINER" >&2
  "${RUN_ARGS[@]}" >/dev/null || fail3 "podman could not create the resident container"
elif [[ "$CUR_STATUS" != "running" ]]; then
  printf '=== seat-resident-run: restarting %s (was %s)\n' "$CONTAINER" "$CUR_STATUS" >&2
  podman start "$CONTAINER" >/dev/null || fail3 "podman could not restart the resident container"
else
  printf '=== seat-resident-run: %s already running\n' "$CONTAINER" >&2
fi
[[ -n "$MAX_RESIDENTS" ]] && exec {ADMIT_FD}>&-

# The tmux SERVER lives on the box HOST, never inside the container: a client that detaches (or a
# laptop that sleeps) leaves the host process running untouched, and re-attaching is `ssh` + `tmux
# attach` — the exact motions the owner already uses, pointed at a different host. The window's
# command execs INTO the resident container for its pty; if the container is killed and recreated,
# re-running this script repairs the window's target without moving the tmux session itself.
if ! tmux has-session -t "$TMUX_SESSION" 2>/dev/null; then
  printf '=== seat-resident-run: starting tmux session %s\n' "$TMUX_SESSION" >&2
  tmux new-session -d -s "$TMUX_SESSION" \
    "podman exec -it $CONTAINER bash $BUNDLE_REL/seat/seat-resident-shell.sh /w/$WORKSPACE_REL" \
    || fail3 "tmux session create failed"
else
  printf '=== seat-resident-run: tmux session %s already present\n' "$TMUX_SESSION" >&2
fi

printf '{"ok":true,"container":"%s","tmuxSession":"%s","host":"%s"}\n' "$CONTAINER" "$TMUX_SESSION" "$(hostname)"
