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

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

if [[ -f .env ]]; then
  set -a
  # shellcheck source=/dev/null
  source .env
  set +a
fi

POOL_DB_NAME="${POOL_DB_NAME:-vexonpool}"
VEX_BIN_DIR="${VEX_BIN_DIR:-/opt/vexon-pool/bin}"
VEX_RPC_PORT="${VEX_RPC_PORT:-18556}"
VEX_RPC_USER="${VEX_RPC_USER:-}"
VEX_RPC_PASSWORD="${VEX_RPC_PASSWORD:-}"
VEX_ADDRESS="${VEX_ADDRESS:-}"
STRATUM_PORT="${STRATUM_PORT:-4499}"
VEX_STRATUM_SYSTEMD_UNIT="${VEX_STRATUM_SYSTEMD_UNIT:-vexon-stratum.service}"
RESTART_STRATUM=0

die() { printf '[FAIL] %s\n' "$1" >&2; exit 1; }
ok() { printf '[OK] %s\n' "$1"; }
warn() { printf '[WARN] %s\n' "$1"; }

usage() {
  cat <<'USAGE'
Usage:
  scripts/repair-miner-address.sh [--restart] [VEX_ADDRESS]

Repairs a miner payout address in the Vexon Pool database so Stratum can
authorize workers such as:

  VEX_ADDRESS.001

The script does not change balances, payouts, wallet files, or chain data. It
only ensures the address exists in accounts and is bound to the VEX coin row.

Examples:
  scripts/repair-miner-address.sh --restart
  scripts/repair-miner-address.sh --restart VsbyU7TV7FeK54Jk5WkGHoYLfGu4fc78cQV
USAGE
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --restart)
      RESTART_STRATUM=1
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    -*)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 2
      ;;
    *)
      VEX_ADDRESS="$1"
      ;;
  esac
  shift
done

command -v mysql >/dev/null 2>&1 || die "mysql client is required"
[[ -n "$VEX_ADDRESS" ]] || die "pass a VEX address or set VEX_ADDRESS in .env"
[[ "$VEX_ADDRESS" =~ ^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,64}$ ]] || die "address is not base58-like: $VEX_ADDRESS"

if [[ -x "$VEX_BIN_DIR/vexonctl" && -n "$VEX_RPC_USER" && -n "$VEX_RPC_PASSWORD" ]]; then
  if "$VEX_BIN_DIR/vexonctl" --notls --rpcserver "127.0.0.1:${VEX_RPC_PORT}" \
      -u "$VEX_RPC_USER" -P "$VEX_RPC_PASSWORD" validateaddress "$VEX_ADDRESS" \
      | grep -q '"isvalid": true'; then
    ok "Vexon node validates address: $VEX_ADDRESS"
  else
    die "Vexon node rejected address: $VEX_ADDRESS"
  fi
else
  warn "skipping node validateaddress probe; vexonctl/RPC env is incomplete"
fi

mysql -uroot "$POOL_DB_NAME" <<SQL
SET @vex_coin_id := (SELECT id FROM coins WHERE symbol='VEX' LIMIT 1);

SELECT @vex_coin_id AS vex_coin_id;

INSERT INTO accounts (username, coinsymbol, coinid, balance, donation, hostaddr)
SELECT '${VEX_ADDRESS}', 'VEX', @vex_coin_id, 0, 0, 'manual-repair'
FROM DUAL
WHERE @vex_coin_id IS NOT NULL
  AND NOT EXISTS (
    SELECT 1 FROM accounts WHERE username='${VEX_ADDRESS}' LIMIT 1
  );

UPDATE accounts
SET coinsymbol='VEX',
    coinid=@vex_coin_id,
    is_locked=0,
    hostaddr=COALESCE(NULLIF(hostaddr,''), 'manual-repair')
WHERE username='${VEX_ADDRESS}'
  AND @vex_coin_id IS NOT NULL;

SELECT id,username,coinsymbol,coinid,balance,is_locked,hostaddr
FROM accounts
WHERE username='${VEX_ADDRESS}'\G
SQL

ok "miner address is bound to the VEX coin row"

if (( RESTART_STRATUM == 1 )); then
  if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files "$VEX_STRATUM_SYSTEMD_UNIT" --no-legend 2>/dev/null | awk '{print $1}' | grep -qx "$VEX_STRATUM_SYSTEMD_UNIT"; then
    systemctl restart "$VEX_STRATUM_SYSTEMD_UNIT"
    ok "restarted $VEX_STRATUM_SYSTEMD_UNIT"
    sleep 3
    if ss -lnt | awk '{print $4}' | grep -Eq "[:.]${STRATUM_PORT}$"; then
      ok "Stratum is listening on $STRATUM_PORT"
    else
      die "Stratum is not listening on $STRATUM_PORT after restart"
    fi
  else
    warn "systemd unit $VEX_STRATUM_SYSTEMD_UNIT not found; restart skipped"
  fi
fi
