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

usage() {
  cat <<'EOF'
Usage:
  ./scripts/cir/run_cir_record_full_delta.sh \
    --out-dir <path> \
    --tal-path <path> \
    --ta-path <path> \
    --cir-tal-uri <url> \
    --payload-replay-archive <path> \
    --payload-replay-locks <path> \
    --payload-base-archive <path> \
    --payload-base-locks <path> \
    --payload-delta-archive <path> \
    --payload-delta-locks <path> \
    [--base-validation-time <rfc3339>] \
    [--delta-validation-time <rfc3339>] \
    [--max-depth <n>] \
    [--max-instances <n>] \
    [--rpki-bin <path>]
EOF
}

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

OUT_DIR=""
TAL_PATH=""
TA_PATH=""
CIR_TAL_URI=""
PAYLOAD_REPLAY_ARCHIVE=""
PAYLOAD_REPLAY_LOCKS=""
PAYLOAD_BASE_ARCHIVE=""
PAYLOAD_BASE_LOCKS=""
PAYLOAD_DELTA_ARCHIVE=""
PAYLOAD_DELTA_LOCKS=""
BASE_VALIDATION_TIME=""
DELTA_VALIDATION_TIME=""
MAX_DEPTH=0
MAX_INSTANCES=1
RPKI_BIN="${RPKI_BIN:-$ROOT_DIR/target/release/rpki}"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --out-dir) OUT_DIR="$2"; shift 2 ;;
    --tal-path) TAL_PATH="$2"; shift 2 ;;
    --ta-path) TA_PATH="$2"; shift 2 ;;
    --cir-tal-uri) CIR_TAL_URI="$2"; shift 2 ;;
    --payload-replay-archive) PAYLOAD_REPLAY_ARCHIVE="$2"; shift 2 ;;
    --payload-replay-locks) PAYLOAD_REPLAY_LOCKS="$2"; shift 2 ;;
    --payload-base-archive) PAYLOAD_BASE_ARCHIVE="$2"; shift 2 ;;
    --payload-base-locks) PAYLOAD_BASE_LOCKS="$2"; shift 2 ;;
    --payload-delta-archive) PAYLOAD_DELTA_ARCHIVE="$2"; shift 2 ;;
    --payload-delta-locks) PAYLOAD_DELTA_LOCKS="$2"; shift 2 ;;
    --base-validation-time) BASE_VALIDATION_TIME="$2"; shift 2 ;;
    --delta-validation-time) DELTA_VALIDATION_TIME="$2"; shift 2 ;;
    --max-depth) MAX_DEPTH="$2"; shift 2 ;;
    --max-instances) MAX_INSTANCES="$2"; shift 2 ;;
    --rpki-bin) RPKI_BIN="$2"; shift 2 ;;
    -h|--help) usage; exit 0 ;;
    *) echo "unknown argument: $1" >&2; usage; exit 2 ;;
  esac
done

[[ -n "$OUT_DIR" && -n "$TAL_PATH" && -n "$TA_PATH" && -n "$CIR_TAL_URI" && -n "$PAYLOAD_REPLAY_ARCHIVE" && -n "$PAYLOAD_REPLAY_LOCKS" && -n "$PAYLOAD_BASE_ARCHIVE" && -n "$PAYLOAD_BASE_LOCKS" && -n "$PAYLOAD_DELTA_ARCHIVE" && -n "$PAYLOAD_DELTA_LOCKS" ]] || {
  usage >&2
  exit 2
}

if [[ ! -x "$RPKI_BIN" ]]; then
  (
    cd "$ROOT_DIR"
    cargo build --release --bin rpki
  )
fi

resolve_validation_time() {
  local path="$1"
  python3 - <<'PY' "$path"
import json, sys
print(json.load(open(sys.argv[1], 'r', encoding='utf-8'))['validationTime'])
PY
}

if [[ -z "$BASE_VALIDATION_TIME" ]]; then
  BASE_VALIDATION_TIME="$(resolve_validation_time "$PAYLOAD_REPLAY_LOCKS")"
fi

if [[ -z "$DELTA_VALIDATION_TIME" ]]; then
  DELTA_VALIDATION_TIME="$(resolve_validation_time "$PAYLOAD_DELTA_LOCKS")"
fi

rm -rf "$OUT_DIR"
mkdir -p "$OUT_DIR/full" "$OUT_DIR/delta-001"
REPO_BYTES_DB="$OUT_DIR/repo-bytes.db"

FULL_DB="$OUT_DIR/full/db"
DELTA_DB="$OUT_DIR/delta-001/db"

"$RPKI_BIN" \
  --db "$FULL_DB" \
  --tal-path "$TAL_PATH" \
  --ta-path "$TA_PATH" \
  --payload-replay-archive "$PAYLOAD_REPLAY_ARCHIVE" \
  --payload-replay-locks "$PAYLOAD_REPLAY_LOCKS" \
  --validation-time "$BASE_VALIDATION_TIME" \
  --max-depth "$MAX_DEPTH" \
  --max-instances "$MAX_INSTANCES" \
  --ccr-out "$OUT_DIR/full/result.ccr" \
  --report-json "$OUT_DIR/full/report.json" \
  --cir-enable \
  --cir-out "$OUT_DIR/full/input.cir" \
  --repo-bytes-db "$REPO_BYTES_DB" \
  --cir-tal-uri "$CIR_TAL_URI" \
  >"$OUT_DIR/full/run.stdout.log" 2>"$OUT_DIR/full/run.stderr.log"

"$RPKI_BIN" \
  --db "$DELTA_DB" \
  --tal-path "$TAL_PATH" \
  --ta-path "$TA_PATH" \
  --payload-base-archive "$PAYLOAD_BASE_ARCHIVE" \
  --payload-base-locks "$PAYLOAD_BASE_LOCKS" \
  --payload-delta-archive "$PAYLOAD_DELTA_ARCHIVE" \
  --payload-delta-locks "$PAYLOAD_DELTA_LOCKS" \
  --payload-base-validation-time "$BASE_VALIDATION_TIME" \
  --validation-time "$DELTA_VALIDATION_TIME" \
  --max-depth "$MAX_DEPTH" \
  --max-instances "$MAX_INSTANCES" \
  --ccr-out "$OUT_DIR/delta-001/result.ccr" \
  --report-json "$OUT_DIR/delta-001/report.json" \
  --cir-enable \
  --cir-out "$OUT_DIR/delta-001/input.cir" \
  --repo-bytes-db "$REPO_BYTES_DB" \
  --cir-tal-uri "$CIR_TAL_URI" \
  >"$OUT_DIR/delta-001/run.stdout.log" 2>"$OUT_DIR/delta-001/run.stderr.log"

python3 - <<'PY' "$OUT_DIR" "$BASE_VALIDATION_TIME" "$DELTA_VALIDATION_TIME"
import json
import os
import sys
from pathlib import Path

out = Path(sys.argv[1])
base_validation_time = sys.argv[2]
delta_validation_time = sys.argv[3]
summary = {
    "version": 1,
    "kind": "cir_pair",
    "baseValidationTime": base_validation_time,
    "deltaValidationTime": delta_validation_time,
    "repoBytesDbPath": "repo-bytes.db",
    "steps": [
        {
            "kind": "full",
            "cirPath": "full/input.cir",
            "ccrPath": "full/result.ccr",
            "reportPath": "full/report.json",
        },
        {
            "kind": "delta",
            "cirPath": "delta-001/input.cir",
            "ccrPath": "delta-001/result.ccr",
            "reportPath": "delta-001/report.json",
            "previous": "full",
        },
    ],
    "repoBytesDbExists": (out / "repo-bytes.db").exists(),
}
(out / "summary.json").write_text(json.dumps(summary, indent=2), encoding="utf-8")
PY

echo "done: $OUT_DIR"
