#!/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

VEX_RPC_PORT="${VEX_RPC_PORT:-18556}"
VEX_WALLET_RPC_PORT="${VEX_WALLET_RPC_PORT:-18557}"
STRATUM_PORT="${STRATUM_PORT:-4499}"
VEX_RPC_USER="${VEX_RPC_USER:-}"
VEX_RPC_PASSWORD="${VEX_RPC_PASSWORD:-}"
VEX_WALLET_RPC_USER="${VEX_WALLET_RPC_USER:-}"
VEX_WALLET_RPC_PASSWORD="${VEX_WALLET_RPC_PASSWORD:-}"
VEX_WALLET_PASSPHRASE="${VEX_WALLET_PASSPHRASE:-}"
VEX_START_WALLET="${VEX_START_WALLET:-0}"
VEX_POOL_ROOT="${VEX_POOL_ROOT:-/opt/vexon-pool}"
VEX_BIN_DIR="${VEX_BIN_DIR:-$VEX_POOL_ROOT/bin}"
VEX_WEB_DIR="${VEX_WEB_DIR:-$VEX_POOL_ROOT/web}"
VEX_STRATUM_CONFIG_DIR="${VEX_STRATUM_CONFIG_DIR:-$VEX_POOL_ROOT/stratum-config}"
VEX_NODE_APPDATA="${VEX_NODE_APPDATA:-/root/.vexond}"
VEX_WALLET_APPDATA="${VEX_WALLET_APPDATA:-/root/.vexonwallet}"
VEX_ENABLE_LOCAL_PEER="${VEX_ENABLE_LOCAL_PEER:-1}"
VEX_PEER_APPDATA="${VEX_PEER_APPDATA:-/root/.vexond-peer}"
VEX_PEER_P2P_PORT="${VEX_PEER_P2P_PORT:-18565}"
VEX_NODE_SCREEN="${VEX_NODE_SCREEN:-Vexon_Node}"
VEX_WALLET_SCREEN="${VEX_WALLET_SCREEN:-Vexon_Wallet}"
VEX_STRATUM_SCREEN="${VEX_STRATUM_SCREEN:-Vexon_Stratum}"
VEX_PEER_SCREEN="${VEX_PEER_SCREEN:-Vexon_Node_Peer}"

start_screen() {
  local name="$1"
  shift
  if screen -ls | grep -q "[.]$name[[:space:]]"; then
    echo "$name already running"
    return
  fi
  screen -dmS "$name" "$@"
}

wait_for_node_rpc() {
  local timeout="${1:-60}"
  local elapsed=0
  until "$VEX_BIN_DIR/vexonctl" \
    --notls \
    --rpcserver "127.0.0.1:${VEX_RPC_PORT}" \
    -u "$VEX_RPC_USER" \
    -P "$VEX_RPC_PASSWORD" \
    getblockcount >/dev/null 2>&1; do
    if (( elapsed >= timeout )); then
      echo "Timed out waiting for Vexon node RPC on 127.0.0.1:${VEX_RPC_PORT}" >&2
      tail -80 "$VEX_NODE_APPDATA/logs/mainnet/vexond.log" 2>/dev/null || true
      return 1
    fi
    sleep 1
    elapsed=$((elapsed + 1))
  done
}

show_stratum_diagnostics() {
  echo
  echo "== Stratum diagnostics =="
  screen -ls || true
  echo
  ps -ef | grep -E 'VexonStratum|Vexon_Stratum|run.sh vexon' | grep -v grep || true
  echo
  ss -lntp | grep -E ":${STRATUM_PORT}\\b" || true
  echo
  tail -80 "$VEX_STRATUM_CONFIG_DIR/vexon.log" 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
      echo "Stratum is listening on $STRATUM_PORT"
      return 0
    fi
    sleep 1
    elapsed=$((elapsed + 1))
  done

  show_stratum_diagnostics
  echo "Timed out waiting for Stratum on 0.0.0.0:${STRATUM_PORT}" >&2
  return 1
}

wait_for_wallet_rpc() {
  local timeout="${1:-60}"
  local elapsed=0

  until "$VEX_BIN_DIR/vexonctl" \
    --wallet \
    --notls \
    --rpcserver "127.0.0.1:${VEX_WALLET_RPC_PORT}" \
    -u "$VEX_WALLET_RPC_USER" \
    -P "$VEX_WALLET_RPC_PASSWORD" \
    getbalance >/dev/null 2>&1; do
    if (( elapsed >= timeout )); then
      echo "Timed out waiting for Vexon wallet RPC on 127.0.0.1:${VEX_WALLET_RPC_PORT}" >&2
      tail -100 "$VEX_WALLET_APPDATA/logs/mainnet/vexonwallet.log" 2>/dev/null || true
      return 1
    fi
    sleep 1
    elapsed=$((elapsed + 1))
  done

  echo "Wallet RPC is responding on $VEX_WALLET_RPC_PORT"
}

start_screen "$VEX_NODE_SCREEN" "$VEX_BIN_DIR/vexond" --appdata="$VEX_NODE_APPDATA" --configfile="$VEX_NODE_APPDATA/vexond.conf"
wait_for_node_rpc 60

if [[ "$VEX_ENABLE_LOCAL_PEER" == "1" ]]; then
  start_screen "$VEX_PEER_SCREEN" "$VEX_BIN_DIR/vexond" --appdata="$VEX_PEER_APPDATA" --configfile="$VEX_PEER_APPDATA/vexond.conf"
  sleep 5
  "$VEX_BIN_DIR/vexonctl" \
    --notls \
    --rpcserver "127.0.0.1:${VEX_RPC_PORT}" \
    -u "$VEX_RPC_USER" \
    -P "$VEX_RPC_PASSWORD" \
    addnode "127.0.0.1:${VEX_PEER_P2P_PORT}" add >/dev/null 2>&1 || true
else
  echo "Skipping $VEX_PEER_SCREEN because VEX_ENABLE_LOCAL_PEER=$VEX_ENABLE_LOCAL_PEER"
fi

if [[ "$VEX_START_WALLET" == "1" ]]; then
  if [[ -z "$VEX_WALLET_PASSPHRASE" ]]; then
    echo "VEX_START_WALLET=1 requires VEX_WALLET_PASSPHRASE in .env" >&2
    exit 1
  fi
  if [[ -z "$VEX_WALLET_RPC_USER" || -z "$VEX_WALLET_RPC_PASSWORD" ]]; then
    echo "VEX_START_WALLET=1 requires VEX_WALLET_RPC_USER and VEX_WALLET_RPC_PASSWORD in .env" >&2
    exit 1
  fi
  scripts/start-wallet-rpc.sh
else
  echo "Skipping $VEX_WALLET_SCREEN because VEX_START_WALLET=$VEX_START_WALLET"
fi

(
  cd "$VEX_STRATUM_CONFIG_DIR"
  start_screen "$VEX_STRATUM_SCREEN" ./run.sh vexon
)
wait_for_stratum_port 30

(
  cd "$VEX_WEB_DIR"
  start_screen vexon-pool-main ./main.sh
  start_screen vexon-pool-loop2 ./loop2.sh
  start_screen vexon-pool-blocks ./blocks.sh
)

"$repo_root/scripts/status.sh"
