#!/usr/bin/env bash
# =============================================================================
#  XDC xone client fragment  —  sourced by one.sh
#  Binary:   xone  (ETH2030 / go-ethereum-derived XDC execution client)
#  Modes:    snap (default) · full · archive · validator
#  Networks: apothem · mainnet (xdc-mainnet) · devnet (xdc-devnet) · net5050
#  Status:   Experimental — research client. Do NOT use for production/real funds.
#            Build: https://github.com/XDCIndia/xOneGo
#
#  xone ships BUILT-IN genesis + bootnodes for apothem / xdc-mainnet / xdc-devnet,
#  so no --bootnodes is required for peering. Override with XDC_BOOTNODES if needed.
#
#  net5050 is a custom stress-test network (chainId 5050).  xone has no built-in
#  genesis for it, so the fragment fetches the genesis JSON, runs xone init, and
#  wires all 5 static peers via a TOML config.  Full sync from genesis is
#  mandatory (#96 — peers serve no snap/fast state for net5050).
#
#  Node types (--mode):
#    snap       -syncmode snap                 fast initial sync (default)
#    full       -syncmode full                 full block execution from genesis
#    archive    -syncmode full -gcmode archive full node, no state pruning
#    validator  -syncmode full -mine …         XDPoS V2 block producer (needs keystore)
#
#  Validator mode requires a funded/authorised signer account:
#    XDC_ETHERBASE        signer address (0x…) for --miner.etherbase (required)
#    XDC_MINER_PASSWORD   path to keystore password file (required to unlock)
#    XDC_UNLOCK           address to unlock (defaults to XDC_ETHERBASE)
#  ONE_SH_VERSION: 1.0.1
# =============================================================================

# net5050 static peers — all 5 validators/bootnodes on the stress-test network.
_NET5050_PEERS='enode://507918630af3a6080867ec3987e9d0054bbb18c97ef38ae39f05f27a13371aab067b2c9e97099c554582b542946742d999e77a84da33f2ac07498a8f03d6c261@65.21.71.4:30550,enode://7d78c32e5dfade9319b1fb564d02fac8aa1474fd01cfa6a6dce689c4f16aa2f742d4492db09930124185f8942abe1bd6b5fa1b2b572f1cbe2641e7411299e14d@65.21.71.4:30552,enode://a4b966a579d1c7abe9f8856a612978db20483ce0eabca2c9ed9768a05d08e2114d14568931fbd3e62fa5f533bfe65d40381ed014c56a67ed8ab212d85bb9d403@65.21.71.4:30554,enode://d2c5ccdc96fe0d4574242572e98057834e7bf5ea6a01afd1e15e81c0bdda735788367581c57f6a79502664d6163c4b3bbb223163382daa1f0c2d3f77d326c709@185.180.220.183:30550,enode://5baefc523ad83eccf9021a1ccb7695496cd4bf82fe96c82557e4238869e50bb8ede9cdb2417d6bde1e04ce000a0186bf3f4f08992fea80703a2788c4342ebf34@95.217.56.168:30551'

# Map the installer's network name → xone's -network value.
# net5050 has no built-in network label — return empty; caller uses --networkid instead.
_xone_network(){
  case "${1:-apothem}" in
    mainnet) echo "xdc-mainnet" ;;
    devnet)  echo "xdc-devnet" ;;
    net5050) echo "" ;;
    *)       echo "apothem" ;;
  esac
}

# Hook: no snapshot published for xone yet.
client_snapshot_name(){
  echo ""
}

# Hook: sync time estimate (no snapshot → sync from genesis).
client_sync_estimate(){
  local _net="${1:-apothem}" _mode="${2:-snap}"
  case "$_net" in
    net5050) echo "minutes–hours (net5050 is small ~361k blocks; full sync from genesis)" ;;
    *)
      case "$_mode" in
        snap) echo "hours–days (snap sync from genesis; no snapshot published)" ;;
        *)    echo "days (full execution sync from genesis; no snapshot published)" ;;
      esac
      ;;
  esac
}

# Hook: pre-flight requirements. Only validator mode has extra needs.
# For net5050: also fetches genesis + runs xone init if chaindata is absent.
client_requirements(){
  if [ "${NODETYPE:-}" = "validator" ]; then
    if [ -z "${XDC_ETHERBASE:-}" ]; then
      err "xone validator mode requires a signer address."
      err "  Set XDC_ETHERBASE=0x… (and XDC_MINER_PASSWORD=/path/to/pwfile to unlock the keystore)."
      return 1
    fi
    if [ -n "${XDC_MINER_PASSWORD:-}" ] && [ ! -f "${XDC_MINER_PASSWORD}" ]; then
      err "XDC_MINER_PASSWORD points to a missing file: ${XDC_MINER_PASSWORD}"
      return 1
    fi
  fi

  # net5050: fetch genesis JSON and init the datadir if chaindata is not yet present.
  if [ "${NETWORK:-}" = "net5050" ]; then
    local _datadir="${DATADIR:-${DIR:-$(pwd)}/data}"
    local _xone_bin="${DIR:-$(pwd)}/xone"
    local _genesis_json="${_datadir}/net5050-genesis.json"
    local _chaindata="${_datadir}/XDC/chaindata"
    if [ ! -d "$_chaindata" ] || [ -z "$(ls -A "$_chaindata" 2>/dev/null)" ]; then
      step "net5050: initialising chaindata from genesis"
      mkdir -p "$_datadir"
      local _genesis_url="${BASE_URL:-https://xdc.network/snapshots}/net5050-genesis.json"
      printf '   %ssource:%s %s\n' "${D:-}" "${N:-}" "$_genesis_url"
      curl -fsSL -A 'Mozilla/5.0' --max-time 60 "$_genesis_url" -o "$_genesis_json" || {
        err "Failed to download net5050 genesis from $_genesis_url"
        err "  Place the genesis JSON at $_genesis_json and re-run."
        return 1
      }
      ok "Genesis JSON downloaded."
      "$_xone_bin" init --datadir "$_datadir" "$_genesis_json" >/dev/null 2>&1 || {
        err "xone init failed — check the genesis JSON and binary."
        return 1
      }
      ok "net5050 chaindata initialised."
    fi

    # Write net5050 TOML config with static peers (idempotent).
    local _toml="${DIR:-$(pwd)}/config-net5050.toml"
    if [ ! -f "$_toml" ]; then
      # Build JSON-array style peer list for geth TOML.
      local _p1='"enode://507918630af3a6080867ec3987e9d0054bbb18c97ef38ae39f05f27a13371aab067b2c9e97099c554582b542946742d999e77a84da33f2ac07498a8f03d6c261@65.21.71.4:30550"'
      local _p2='"enode://7d78c32e5dfade9319b1fb564d02fac8aa1474fd01cfa6a6dce689c4f16aa2f742d4492db09930124185f8942abe1bd6b5fa1b2b572f1cbe2641e7411299e14d@65.21.71.4:30552"'
      local _p3='"enode://a4b966a579d1c7abe9f8856a612978db20483ce0eabca2c9ed9768a05d08e2114d14568931fbd3e62fa5f533bfe65d40381ed014c56a67ed8ab212d85bb9d403@65.21.71.4:30554"'
      local _p4='"enode://d2c5ccdc96fe0d4574242572e98057834e7bf5ea6a01afd1e15e81c0bdda735788367581c57f6a79502664d6163c4b3bbb223163382daa1f0c2d3f77d326c709@185.180.220.183:30550"'
      local _p5='"enode://5baefc523ad83eccf9021a1ccb7695496cd4bf82fe96c82557e4238869e50bb8ede9cdb2417d6bde1e04ce000a0186bf3f4f08992fea80703a2788c4342ebf34@95.217.56.168:30551"'
      cat > "$_toml" <<TOML
[Node.P2P]
StaticNodes  = [$_p1,$_p2,$_p3,$_p4,$_p5]
TrustedNodes = [$_p1,$_p2,$_p3,$_p4,$_p5]
TOML
      ok "net5050 TOML config written: $_toml"
    fi
  fi

  return 0
}

# Hook: launch arguments. Signature: client_start_args <network> <mode>
client_start_args(){
  local _net="${1:-apothem}" _mode="${2:-snap}"
  local _datadir="${DATADIR:-$DIR/data}"
  local _xnet; _xnet=$(_xone_network "$_net")

  # Mode → sync/prune/miner flags.
  local _mode_args=""
  case "$_mode" in
    snap)      _mode_args="-syncmode snap" ;;
    full)      _mode_args="-syncmode full" ;;
    archive)   _mode_args="-syncmode full -gcmode archive" ;;
    validator)
      _mode_args="-syncmode full -mine -miner.etherbase \"${XDC_ETHERBASE}\""
      [ -n "${XDC_MINER_PASSWORD:-}" ] && _mode_args="$_mode_args -password \"${XDC_MINER_PASSWORD}\" -unlock \"${XDC_UNLOCK:-$XDC_ETHERBASE}\""
      ;;
    *)         _mode_args="-syncmode snap" ;;
  esac

  # Optional operator-supplied bootnodes (xone has sane built-ins otherwise).
  local _boot_args=""
  [ -n "${XDC_BOOTNODES:-}" ] && _boot_args="-bootnodes \"${XDC_BOOTNODES}\""

  # net5050: custom stress-test network — no built-in genesis/peers in xone.
  # Uses --networkid 5050 + explicit static peers (TOML config) + forced full sync.
  # ethstats is wired so the node appears on stats.xdcindia.com.
  if [ "$_net" = "net5050" ]; then
    local _toml="${DIR:-$(pwd)}/config-net5050.toml"
    local _ethstats_name="${HOST:-xdcnode}-net5050-${_mode:-full}-${OSID:-os}"
    local _ethstats_flag="-ethstats \"${_ethstats_name}:${STATS_SECRET:-xdc_openscan_stats_2026}@stats.xdcindia.com:443\""
    # Force full sync regardless of requested mode — no snap/fast state available (#96).
    local _net5050_sync="-syncmode full"
    case "$_mode" in
      archive) _net5050_sync="-syncmode full -gcmode archive" ;;
      validator)
        _net5050_sync="-syncmode full -mine -miner.etherbase \"${XDC_ETHERBASE}\""
        [ -n "${XDC_MINER_PASSWORD:-}" ] && _net5050_sync="$_net5050_sync -password \"${XDC_MINER_PASSWORD}\" -unlock \"${XDC_UNLOCK:-$XDC_ETHERBASE}\""
        ;;
    esac
    printf '%s' "\
-datadir \"$_datadir\" \
-networkid 5050 \
-config \"$_toml\" \
-http -http.addr 127.0.0.1 -http.port \"${RPC_PORT:-8615}\" \
-http.api eth,net,web3,debug,txpool,admin \
-ws -ws.addr 127.0.0.1 -ws.port \"${WS_PORT:-8616}\" -ws.api eth,net,web3 \
-authrpc.addr 127.0.0.1 -authrpc.port \"${AUTH_PORT:-8617}\" \
-port \"${P2P_PORT:-30356}\" \
-maxpeers ${MAXPEERS:-50} \
$_net5050_sync \
$_ethstats_flag \
-verbosity ${VERBOSITY:-3}"
    return
  fi

  printf '%s' "\
-datadir \"$_datadir\" \
-network \"$_xnet\" \
-http -http.addr 127.0.0.1 -http.port \"${RPC_PORT:-8615}\" \
-http.api eth,net,web3,debug,txpool,admin \
-ws -ws.addr 127.0.0.1 -ws.port \"${WS_PORT:-8616}\" -ws.api eth,net,web3 \
-authrpc.addr 127.0.0.1 -authrpc.port \"${AUTH_PORT:-8617}\" \
-port \"${P2P_PORT:-30356}\" \
-maxpeers ${MAXPEERS:-50} \
$_boot_args \
$_mode_args \
-verbosity ${VERBOSITY:-3}"
}

# Hook: RPC port for health-check.
client_rpc_port(){ echo "${RPC_PORT:-8615}"; }

# Hook: generic SIGTERM stop.
client_stop(){ return 0; }
