#!/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_ADDRESS="${VEX_ADDRESS:-}"
VEX_RPC_USER="${VEX_RPC_USER:-}"
VEX_RPC_PASSWORD="${VEX_RPC_PASSWORD:-}"
VEX_RPC_PORT="${VEX_RPC_PORT:-18556}"
VEX_BLOCK_SUBMIT_DIFF="${VEX_BLOCK_SUBMIT_DIFF:-503382015}"
VEX_MIN_PAYOUT="${VEX_MIN_PAYOUT:-0.001}"
VEX_MATURE_BLOCKS="${VEX_MATURE_BLOCKS:-100}"
VEX_TXFEE="${VEX_TXFEE:-0}"
VEX_STRATUM_CONFIG_DIR="${VEX_STRATUM_CONFIG_DIR:-/opt/vexon-pool/stratum-config}"
VEX_STRATUM_SCREEN="${VEX_STRATUM_SCREEN:-Vexon_Stratum}"
STRATUM_PORT="${STRATUM_PORT:-4499}"
RESTART_STRATUM=1
VEX_STRATUM_SYSTEMD_UNIT="${VEX_STRATUM_SYSTEMD_UNIT:-vexon-stratum.service}"

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

usage() {
  cat <<'USAGE'
Usage:
  scripts/repair-vex-coin.sh [--no-restart]

Repairs the VEX coin database row. By default, it restarts the screen-based
Stratum launcher. Use --no-restart when systemd is responsible for Stratum.
USAGE
}

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

show_stratum_diagnostics() {
  printf '\n== Stratum diagnostics ==\n' >&2
  screen -ls >&2 || true
  printf '\n-- processes --\n' >&2
  ps -ef | grep -E 'VexonStratum|Vexon_Stratum|run.sh vexon' | grep -v grep >&2 || true
  printf '\n-- listening ports --\n' >&2
  ss -lntp | grep -E ":${STRATUM_PORT}\\b" >&2 || true
  printf '\n-- stratum log --\n' >&2
  tail -80 "$VEX_STRATUM_CONFIG_DIR/vexon.log" >&2 2>/dev/null || true
}

wait_for_stratum_port() {
  local timeout="${1:-30}"
  local elapsed=0

  while (( elapsed < timeout )); do
    if ss -lnt | awk '{print $4}' | grep -Eq "[:.]${STRATUM_PORT}$"; then
      ok "Stratum is listening on $STRATUM_PORT"
      return 0
    fi
    sleep 1
    elapsed=$((elapsed + 1))
  done

  show_stratum_diagnostics
  die "Stratum did not start listening on $STRATUM_PORT within ${timeout}s"
}

systemd_unit_exists() {
  local unit="$1"
  command -v systemctl >/dev/null 2>&1 || return 1
  systemctl list-unit-files "$unit" --no-legend 2>/dev/null | awk '{print $1}' | grep -qx "$unit"
}

command -v mysql >/dev/null 2>&1 || die "mysql client is required"
[[ -n "$VEX_ADDRESS" ]] || die "VEX_ADDRESS is not set"
[[ -n "$VEX_RPC_USER" ]] || die "VEX_RPC_USER is not set"
[[ -n "$VEX_RPC_PASSWORD" ]] || die "VEX_RPC_PASSWORD is not set"
[[ "$VEX_MIN_PAYOUT" =~ ^[0-9]+([.][0-9]+)?$ ]] || die "VEX_MIN_PAYOUT must be numeric"
[[ "$VEX_MATURE_BLOCKS" =~ ^[1-9][0-9]*$ ]] || die "VEX_MATURE_BLOCKS must be a positive integer"
[[ "$VEX_TXFEE" =~ ^[0-9]+([.][0-9]+)?$ ]] || die "VEX_TXFEE must be numeric"

mysql -uroot "$POOL_DB_NAME" <<SQL
UPDATE coins SET
  name='Vexon',
  symbol='VEX',
  symbol2='',
  algo='decred',
  rpcencoding='DCR',
  master_wallet='${VEX_ADDRESS}',
  image='/vexon/ui/images/vexon-logo.png',
  enable=1,
  auto_ready=1,
  visible=1,
  installed=1,
  reward=50,
  price=0,
  txfee=${VEX_TXFEE},
  block_time=300,
  mature_blocks=${VEX_MATURE_BLOCKS},
  payout_min=${VEX_MIN_PAYOUT},
  difficulty=${VEX_BLOCK_SUBMIT_DIFF},
  rpchost='127.0.0.1',
  rpcport=${VEX_RPC_PORT},
  rpcuser='${VEX_RPC_USER}',
  rpcpasswd='${VEX_RPC_PASSWORD}',
  hassubmitblock=1,
  usememorypool=1,
  rpccurl=1,
  rpcssl=0,
  rpccert='',
  account=''
WHERE symbol='VEX';

SELECT id,name,symbol,enable,auto_ready,algo,rpcencoding,rpcport,payout_min,mature_blocks,txfee,master_wallet
FROM coins
WHERE symbol='VEX'\G
SQL

ok "VEX coin row repaired in database $POOL_DB_NAME"

if (( RESTART_STRATUM == 0 )); then
  ok "Stratum restart skipped by --no-restart"
elif systemd_unit_exists "$VEX_STRATUM_SYSTEMD_UNIT"; then
  systemctl restart "$VEX_STRATUM_SYSTEMD_UNIT"
  ok "restarted $VEX_STRATUM_SYSTEMD_UNIT"
  wait_for_stratum_port 30
elif [[ -d "$VEX_STRATUM_CONFIG_DIR" && -x "$VEX_STRATUM_CONFIG_DIR/run.sh" ]]; then
  if command -v screen >/dev/null 2>&1; then
    screen -S "$VEX_STRATUM_SCREEN" -X quit >/dev/null 2>&1 || true
    sleep 2
    (
      cd "$VEX_STRATUM_CONFIG_DIR"
      screen -dmS "$VEX_STRATUM_SCREEN" ./run.sh vexon
    )
    ok "restarted $VEX_STRATUM_SCREEN from $VEX_STRATUM_CONFIG_DIR"
    wait_for_stratum_port 30
  else
    ok "screen not found; VEX coin row repaired but Stratum was not restarted"
  fi
else
  ok "Stratum config directory not found; VEX coin row repaired but Stratum was not restarted"
fi
