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

die() { printf 'error: %s\n' "$*" >&2; exit 2; }
roles=(victim-read victim-mixed aggressor-scan)
case_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
repo_root="$(cd "$case_dir/../.." && pwd -P)"
usage() { printf 'usage: %s <experiment-id> --round-id <id> [--aggressor-operation-runtime-overrides <json>] [--common-rerun-argv ... --end-argv] [--victim-read-rerun-argv ... --end-argv] [--victim-mixed-rerun-argv ... --end-argv] [--aggressor-scan-rerun-argv ... --end-argv]\n' "$0" >&2; exit 2; }
valid_id() { [[ "$1" =~ ^[a-z][a-z0-9-]{0,62}$ ]]; }
attempt() { printf '%s/runs/%s-%s/attempt-001' "$repo_root" "$1" "$2"; }
reserved() { [[ "$1" == --from-attempt || "$1" == --from-manifest || "$1" == --try || "$1" == --tipoc || "$1" == --dry-run || "$1" == --sync-try-to-pressure-nodes || "$1" == --pressure-nodes || "$1" == --concurrency-steps || "$1" == --help ]]; }

[[ $# -ge 3 ]] || usage
experiment="$1"; shift; valid_id "$experiment" || die 'invalid experiment id'
round=''; operation_overrides=''; common=(); read_args=(); mixed_args=(); aggressor_args=(); active=''
while [[ $# -gt 0 ]]; do
  case "$1" in
    --round-id) [[ $# -ge 2 ]] || usage; round="$2"; shift 2 ;;
    --aggressor-operation-runtime-overrides) [[ $# -ge 2 ]] || usage; operation_overrides="$2"; shift 2 ;;
    --common-rerun-argv) active=common; shift ;;
    --victim-read-rerun-argv) active=read; shift ;;
    --victim-mixed-rerun-argv) active=mixed; shift ;;
    --aggressor-scan-rerun-argv) active=aggressor; shift ;;
    --end-argv) active=''; shift ;;
    *) [[ -n "$active" ]] || usage; reserved "$1" && die "case controls $1"; case "$active" in common) common+=("$1");; read) read_args+=("$1");; mixed) mixed_args+=("$1");; aggressor) aggressor_args+=("$1");; esac; shift ;;
  esac
done
valid_id "$round" || die 'round id is required and must be lowercase letters, digits, and hyphens'
[[ -z "$operation_overrides" || -f "$operation_overrides" ]] || die 'operation runtime overrides file does not exist'
[[ -n "${ENV_FILE:-}" && -f "$ENV_FILE" ]] || die 'ENV_FILE is required'
set -a; source "$ENV_FILE"; set +a
[[ -x "${TIPOC_BIN:-}" ]] || die 'TIPOC_BIN is required and executable'
run_again="$repo_root/scripts/rerun/run-again.sh"; [[ -x "$run_again" ]] || die 'native run-again.sh is missing'
control="$repo_root/output/three-cluster-interference/$experiment/rounds/$round"; mkdir -p "$control"
lock="$repo_root/output/three-cluster-interference/$experiment/execution.lock"
mkdir "$lock" 2>/dev/null || die "an execution is already active for $experiment"
trap 'rmdir "$lock" 2>/dev/null || true' EXIT
printf '%q ' "$@" >"$control/raw-argv.txt"

plans=()
for role in "${roles[@]}"; do
  root="$(attempt "$experiment" "$role")"; [[ -f "$root/run-profile-manifest.json" ]] || die "missing attempt for $role"
  case "$role" in
    victim-read) extra=("${read_args[@]}") ;;
    victim-mixed) extra=("${mixed_args[@]}") ;;
    aggressor-scan) extra=("${aggressor_args[@]}") ;;
  esac
  "$run_again" --from-attempt "$root" --try auto --tipoc "$TIPOC_BIN" --dry-run "${common[@]}" "${extra[@]}" >"$control/$role-dry-run.log" 2>&1
  planned="$(find "$root/run" -maxdepth 1 -type d -name 'try-*' | sort | tail -1)"
  [[ -n "$planned" && -f "$planned/run-profile-manifest.json" ]] || die "dry-run did not materialize a try for $role"
  "$TIPOC_BIN" run preflight --manifest "$planned/run-profile-manifest.json" >"$planned/preflight-receipt.json"
  jq -e '.status == "compatible"' "$planned/preflight-receipt.json" >/dev/null || die "try preflight is not compatible for $role"
  plans+=("$planned/run-profile-manifest.json")
done
pids=(); status=0
for index in "${!plans[@]}"; do
  mf="${plans[$index]}"; role="${roles[$index]}"
  run_args=(run --manifest "$mf")
  if [[ "$role" == aggressor-scan && -n "$operation_overrides" ]]; then
    run_args+=(--operation-runtime-overrides "$operation_overrides")
  fi
  "$TIPOC_BIN" "${run_args[@]}" >"$(dirname "$mf")/case-rerun.log" 2>&1 & pids+=("$!")
done
for pid in "${pids[@]}"; do wait "$pid" || status=1; done
exit "$status"
