#!/usr/bin/env bash
# Harvest (height, hash) checkpoint pairs from a running zclassicd.
# Emits two C source fragments for lib/chain/src/chainparams.c:
#   /tmp/checkpoints_decl.c  — the array declaration (heights only)
#   /tmp/checkpoints_init.c  — the uint256_set_hex initializers
#
# Trust model: local zclassicd is an advisory reference. Its
# (height,hash) sequence below the explicit 10-block finality floor is
# useful only when it also matches zclassic23 anchors/quorum.
#
# Usage: tools/harvest_checkpoints.sh
set -euo pipefail

RPC_USER="${RPC_USER:-zclrhett}"
RPC_PASS="${RPC_PASS:-zclrhettpass2026}"
RPC_PORT="${RPC_PORT:-8232}"
STEP="${STEP:-50000}"
OUT_DECL="${OUT_DECL:-/tmp/checkpoints_decl.c}"
OUT_INIT="${OUT_INIT:-/tmp/checkpoints_init.c}"
OUT_COUNT="${OUT_COUNT:-/tmp/checkpoints_count.txt}"

python3 - "$OUT_DECL" "$OUT_INIT" "$OUT_COUNT" <<PYEOF
import json, sys, urllib.request, base64

USER, PASS, PORT, STEP = "$RPC_USER", "$RPC_PASS", $RPC_PORT, $STEP
out_decl, out_init, out_count = sys.argv[1], sys.argv[2], sys.argv[3]

def rpc(method, params=None):
    body = json.dumps({"jsonrpc":"1.0","method":method,
                       "params":params or [], "id":1}).encode()
    auth = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
    req = urllib.request.Request(f"http://127.0.0.1:{PORT}/", data=body,
        headers={"Authorization": f"Basic {auth}",
                 "Content-Type": "text/plain"})
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.loads(r.read())["result"]

tip = rpc("getblockcount")
finalized = tip - 10
heights = [0] + list(range(STEP, finalized + 1, STEP))
hashes = []
for h in heights:
    bh = rpc("getblockhash", [h])
    if not isinstance(bh, str) or len(bh) != 64:
        sys.exit(f"bad hash at h={h}: {bh!r}")
    hashes.append(bh)

with open(out_decl, "w") as f:
    f.write(f"/* Harvested from local zclassicd tip={tip}, "
            f"finalized through height {finalized}.\n"
            " * Generated by tools/harvest_checkpoints.sh — do not hand-edit. */\n"
            "static struct checkpoint_entry mainnet_checkpoints[] = {\n")
    for h in heights:
        f.write(f"    {{ {h}, {{{{0}}}} }},\n")
    f.write("};\n")

with open(out_init, "w") as f:
    f.write(f"    /* {len(heights)} checkpoints, harvested by "
            "tools/harvest_checkpoints.sh */\n")
    for i, (h, bh) in enumerate(zip(heights, hashes)):
        f.write(f"    uint256_set_hex(&mainnet_checkpoints[{i}].hash,\n"
                f"        \"{bh}\");  /* h={h} */\n")

with open(out_count, "w") as f:
    f.write(str(len(heights)))

print(f"wrote {out_decl}, {out_init}, {out_count}: {len(heights)} entries, "
      f"deepest at height {heights[-1]}")
PYEOF
