#!/usr/bin/env bash
# Public trinity-b snapshot restore. Install-only. Does not start the node.
#   curl -fsSL https://trinity-b-snapshot.secret3.dev/restore.sh | bash
#
# Refuses mainnet vals/archives/snapshot-node and all Trinity guests
# (vals and the producer/RPC set).

set -euo pipefail

BASE="${SNAPSHOT_BASE:-https://trinity-b-snapshot.secret3.dev}"
HOME_DIR="${HOME}"
NODE_HOME="${NODE_HOME:-${HOME_DIR}/.secretd}"
DATA="${NODE_HOME}/data"
SERVICE="${SERVICE:-trinity-node}"
WORKDIR="${TMPDIR:-/tmp}/trinity-snapshot-restore"

die() { echo "FATAL: $*" >&2; exit 1; }
ok() { echo "OK  $*"; }

host="$(hostname -s 2>/dev/null || hostname)"
case "$host" in
  snodes-val|lisa-val|archive-01|archive-00|snapshot-node|s2-g00|spare-00|spare-01|spare-02)
    die "refusing hostname ${host}; this is the Trinity snapshot, not mainnet"
    ;;
  testnet-00|testnet-01|testnet-02|testnet-03|testnet-04|testnet-05|testnet-06|testnet-07)
    die "refusing Trinity lab hostname ${host}; restore is not for 00-07"
    ;;
esac

command -v curl >/dev/null || die "curl missing"
command -v tar >/dev/null || die "tar missing"
command -v sha256sum >/dev/null || die "sha256sum missing"
command -v zstd >/dev/null || command -v pzstd >/dev/null || die "zstd missing"
command -v jq >/dev/null || die "jq missing"

mkdir -p "$WORKDIR"
cd "$WORKDIR"

echo "Fetching ${BASE}/latest.json"
curl -fsSL "${BASE}/latest.json" -o latest.json
chain="$(jq -r '.chain_id // empty' latest.json)"
[[ "$chain" == "trinity-b" ]] || die "unexpected chain_id ${chain} (want trinity-b)"
file="$(jq -r '.file // empty' latest.json)"
sha="$(jq -r '.sha256 // empty' latest.json)"
size="$(jq -r '.size_bytes // 0' latest.json)"
unpacked="$(jq -r '.unpacked_bytes // 0' latest.json)"
height="$(jq -r '.height // empty' latest.json)"
[[ -n "$file" && "$file" != "null" ]] || die "latest.json has no pack file yet"
[[ -n "$sha" && "$sha" =~ ^[0-9a-fA-F]{64}$ ]] || die "latest.json missing sha256"
[[ "$height" =~ ^[0-9]+$ ]] || die "latest.json missing height"

if [[ -s "${NODE_HOME}/config/genesis.json" ]]; then
  existing="$(jq -r '.chain_id // empty' "${NODE_HOME}/config/genesis.json")"
  [[ "$existing" == "trinity-b" || -z "$existing" ]] \
    || die "existing genesis chain_id ${existing} is not trinity-b"
fi

url="${BASE}/${file}"
echo "Snapshot height=${height} file=${file}"

need=$((size + unpacked + 10 * 1024 * 1024 * 1024))
avail="$(df -B1 --output=avail "$HOME_DIR" | tail -1 | tr -d ' ')"
[[ "$avail" -gt "$need" ]] || die "not enough free space (have ${avail} need ~${need})"

echo "Downloading ${url}"
curl -fL --retry 3 -C - -o "$file" "$url"
echo "${sha}  ${file}" | sha256sum --check

if command -v systemctl >/dev/null; then
  sudo systemctl stop "$SERVICE" 2>/dev/null || true
  sudo systemctl stop secret-node.service 2>/dev/null || true
fi

if [[ -d "${NODE_HOME}/.node" ]]; then
  node_bak="$(mktemp -d "${WORKDIR}/node.XXXXXX")"
  cp -a "${NODE_HOME}/.node"/. "$node_bak"/
fi
rm -rf "$DATA"
mkdir -p "$NODE_HOME"

set -o pipefail
if command -v pzstd >/dev/null; then
  pzstd -dc "$file" | tar -xf - -C "$NODE_HOME"
else
  zstd -dc "$file" | tar -xf - -C "$NODE_HOME"
fi

if [[ -n "${node_bak:-}" ]]; then
  mkdir -p "${NODE_HOME}/.node"
  cp -a "$node_bak"/. "${NODE_HOME}/.node"/
fi

mkdir -p "$DATA"
cat > "${DATA}/priv_validator_state.json" <<'STATE'
{"height":"0","round":0,"step":0}
STATE

[[ -d "${DATA}/application.db" ]] || die "extract finished but application.db is missing"
got="$(jq -r '.chain_id // empty' "${NODE_HOME}/config/genesis.json" 2>/dev/null || true)"
[[ "$got" == "trinity-b" ]] || die "extracted genesis chain_id ${got:-missing} is not trinity-b"

ok "extracted trinity-b height=${height} into ${NODE_HOME}"
echo "Start the node yourself. This script does not enable trinity-node or secret-node."
