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

usage() {
  cat <<'EOF'
Usage:
  run_routinator_from_local_tree.sh \
    --routinator-bin <path> \
    --mirror-root <local-rsync-mirror-root> \
    --tal-dir <dir> | --tal <file>... \
    --out-dir <path> \
    [--validation-time <RFC3339>] \
    [--real-rsync-bin <path>] \
    [--enable-aspa]

The input mirror is prepared by the caller. This script does not generate it.
Pass --validation-time only if FAKETIME_LIB points to a working libfaketime
library; otherwise Routinator will validate at wall-clock time.
Example:
  export FAKETIME_LIB=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1
EOF
}

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROUTINATOR_BIN=""
MIRROR_ROOT=""
OUT_DIR=""
VALIDATION_TIME=""
REAL_RSYNC_BIN="${REAL_RSYNC_BIN:-/usr/bin/rsync}"
ENABLE_ASPA=0
TAL_DIR=""
TALS=()

while [[ $# -gt 0 ]]; do
  case "$1" in
    --routinator-bin) ROUTINATOR_BIN="$2"; shift 2 ;;
    --mirror-root) MIRROR_ROOT="$2"; shift 2 ;;
    --tal-dir) TAL_DIR="$2"; shift 2 ;;
    --tal) TALS+=("$2"); shift 2 ;;
    --out-dir) OUT_DIR="$2"; shift 2 ;;
    --validation-time) VALIDATION_TIME="$2"; shift 2 ;;
    --real-rsync-bin) REAL_RSYNC_BIN="$2"; shift 2 ;;
    --enable-aspa) ENABLE_ASPA=1; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "unknown argument: $1" >&2; usage >&2; exit 2 ;;
  esac
done

[[ -n "$ROUTINATOR_BIN" && -n "$MIRROR_ROOT" && -n "$OUT_DIR" ]] || { usage >&2; exit 2; }
[[ -x "$ROUTINATOR_BIN" ]] || { echo "routinator binary not executable: $ROUTINATOR_BIN" >&2; exit 2; }
[[ -d "$MIRROR_ROOT" ]] || { echo "mirror root not found: $MIRROR_ROOT" >&2; exit 2; }
if [[ -z "$TAL_DIR" && "${#TALS[@]}" -eq 0 ]]; then
  echo "provide --tal-dir or at least one --tal" >&2
  exit 2
fi

mkdir -p "$OUT_DIR"
WORK_DIR="$OUT_DIR/work"
REPO_DIR="$WORK_DIR/repository"
EXTRA_TALS="$WORK_DIR/tals"
CONFIG_FILE="$WORK_DIR/routinator.conf"
rm -rf "$WORK_DIR"
mkdir -p "$REPO_DIR" "$EXTRA_TALS"

PREPARE_TAL_ARGS=(--out-dir "$EXTRA_TALS" --summary "$OUT_DIR/prepared-tals.json")
if [[ -n "$TAL_DIR" ]]; then
  PREPARE_TAL_ARGS+=(--tal-dir "$TAL_DIR")
fi
for tal in "${TALS[@]}"; do
  PREPARE_TAL_ARGS+=(--tal "$tal")
done
python3 "$SCRIPT_DIR/prepare_tals.py" "${PREPARE_TAL_ARGS[@]}"

cat > "$CONFIG_FILE" <<EOF
repository-dir = "$REPO_DIR"
no-rir-tals = true
extra-tals-dir = "$EXTRA_TALS"
disable-rrdp = true
rrdp-fallback = "never"
rsync-command = "$SCRIPT_DIR/cir-rsync-wrapper"
EOF

export CIR_MIRROR_ROOT="$(cd "$MIRROR_ROOT" && pwd)"
export REAL_RSYNC_BIN="$REAL_RSYNC_BIN"
export CIR_LOCAL_LINK_MODE=1
export LOCAL_REPO_REPLAY_VALIDATION_TIME="$VALIDATION_TIME"
export LOCAL_REPO_REPLAY_OUT_DIR="$OUT_DIR"

ARGS=(
  "$ROUTINATOR_BIN"
  --config "$CONFIG_FILE"
  --repository-dir "$REPO_DIR"
  --disable-rrdp
  --rrdp-fallback never
  --rsync-command "$SCRIPT_DIR/cir-rsync-wrapper"
  --no-rir-tals
  --extra-tals-dir "$EXTRA_TALS"
)
if [[ "$ENABLE_ASPA" -eq 1 ]]; then
  echo 'enable-aspa = true' >> "$CONFIG_FILE"
  ARGS+=(--enable-aspa)
fi
if [[ -n "$VALIDATION_TIME" && -z "${FAKETIME_LIB:-}" ]]; then
  echo "warning: --validation-time is ignored for Routinator because FAKETIME_LIB is not set" >&2
fi
VRP_ARGS=(vrps -o "$OUT_DIR/vrps.csv")
JSON_ARGS=(vrps -f jsonext -o "$OUT_DIR/routinator.json")

/usr/bin/time -v -o "$OUT_DIR/process-time.txt" bash -c '
  set -euo pipefail
  if [[ -n "$LOCAL_REPO_REPLAY_VALIDATION_TIME" && -n "${FAKETIME_LIB:-}" ]]; then
    faketime_value="$(python3 - <<'"'"'PY'"'"' "$LOCAL_REPO_REPLAY_VALIDATION_TIME"
from datetime import datetime, timezone
import sys
dt = datetime.fromisoformat(sys.argv[1].replace("Z", "+00:00")).astimezone(timezone.utc)
print("@" + dt.strftime("%Y-%m-%d %H:%M:%S"))
PY
)"
    export LD_PRELOAD="$FAKETIME_LIB"
    export TZ=UTC
    unset FAKETIME_FMT
    export FAKETIME="$faketime_value"
    export FAKETIME_DONT_FAKE_MONOTONIC=1
  fi
  "$@" update --complete >"$LOCAL_REPO_REPLAY_OUT_DIR/update.log" 2>&1 || true
  "$@" vrps -o "$LOCAL_REPO_REPLAY_OUT_DIR/vrps.csv" >"$LOCAL_REPO_REPLAY_OUT_DIR/vrps.log" 2>&1
  "$@" vrps -f jsonext -o "$LOCAL_REPO_REPLAY_OUT_DIR/routinator.json" >"$LOCAL_REPO_REPLAY_OUT_DIR/json.log" 2>&1
' local_repo_replay "${ARGS[@]}"
python3 "$SCRIPT_DIR/normalize_rp_outputs.py" --kind routinator --input "$OUT_DIR/routinator.json" --vrps-out "$OUT_DIR/vrps.normalized.txt" --vaps-out "$OUT_DIR/vaps.normalized.txt"
python3 "$SCRIPT_DIR/summarize_replay.py" --rp routinator --out-dir "$OUT_DIR" --summary "$OUT_DIR/summary.json"
echo "done: $OUT_DIR"
