#!/usr/bin/env bash
# Pearl mainnet — alpha-miner + HR на пул через Stratum :9112 (тот же порт, что майнинг).
set -euo pipefail

PEARL_POOL="stratum+tcp://pearl.th0rn.space:9112"
PEARL_ADDRESS="prl1p99zrxmsuuysdkmpmgu82jefet3t2ls0utvkt5prv32uf5rjmy02sestxrl"
# Для multi-GPU задайте имя рига как в Stratum (eth79x9 → воркеры eth79x9.gpu0 …)
PEARL_WORKER="${PEARL_WORKER:-$(hostname)}"
PEARL_PASSWORD="x"
STATUS_INTERVAL=20
REPORT_INTERVAL=15
REPORT_HR=1

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MINER="${DIR}/alpha-miner"
LOG="${DIR}/miner.log"

if [[ ! -x "$MINER" ]]; then
  echo "Нет ${MINER}" >&2
  exit 1
fi

STRATUM_WORKER="${PEARL_ADDRESS}.${PEARL_WORKER}"
STRATUM_HOST=""
STRATUM_PORT=""
if [[ "$PEARL_POOL" =~ ^stratum\+tcp://([^:/]+):([0-9]+) ]]; then
  STRATUM_HOST="${BASH_REMATCH[1]}"
  STRATUM_PORT="${BASH_REMATCH[2]}"
fi

MINER_ARGS=(
  --pool "$PEARL_POOL"
  --address "$PEARL_ADDRESS"
  --worker "$PEARL_WORKER"
  --password "$PEARL_PASSWORD"
  --status-interval "$STATUS_INTERVAL"
)
MINER_ARGS+=("$@")

if [[ "${RUN_MODE:-}" == "direct" ]]; then
  exec "$MINER" "${MINER_ARGS[@]}"
fi

_hr_report() {
  local worker="$1" th="$2"
  [[ "$REPORT_HR" == "1" ]] || return 0
  [[ -n "$STRATUM_HOST" && -n "$STRATUM_PORT" ]] || return 0
  local payload
  payload=$(printf '{"jsonrpc":"2.0","id":1,"method":"pearl.report_hashrate","params":["%s",%s]}\n' \
    "$worker" "$th")
  if command -v nc >/dev/null 2>&1; then
    if printf '%s' "$payload" | nc -w4 "$STRATUM_HOST" "$STRATUM_PORT" >/dev/null 2>&1; then
      return 0
    fi
  fi
  if timeout 4 bash -c "exec 3<>/dev/tcp/${STRATUM_HOST}/${STRATUM_PORT} && printf '%s' '$payload' >&3" 2>/dev/null; then
    return 0
  fi
  echo "run.sh: не удалось отправить HR ${th} TH/s (worker=${worker})" >&2
}

_tail_and_hr() {
  declare -A GPU_SUM
  local sum="0" last_report=0 now val gpu_id=""
  _flush_hr() {
    local g w had_gpu=0 n_gpu=0 val
    for g in "${!GPU_SUM[@]}"; do ((n_gpu++)) || true; done
    for g in "${!GPU_SUM[@]}"; do
      val="${GPU_SUM[$g]}"
      w="${STRATUM_WORKER}.${g}"
      _hr_report "$w" "$val"
      # 1 карта: в логе gpu=0, Stratum-воркер без суффикса (Hive / rig) — шлём и туда.
      if (( n_gpu == 1 )); then
        _hr_report "$STRATUM_WORKER" "$val"
      fi
      unset 'GPU_SUM[$g]'
      had_gpu=1
    done
    # Строки без gpu= (старый формат лога) — только на STRATUM_WORKER.
    if (( !had_gpu )) && awk -v s="$sum" 'BEGIN { exit (s > 0) ? 0 : 1 }'; then
      _hr_report "$STRATUM_WORKER" "$sum"
    fi
    sum="0"
  }
  while IFS= read -r line || [[ -n "$line" ]]; do
    printf '%s\n' "$line"
    gpu_id=""
    if [[ "$line" =~ gpu=([0-9]+) ]]; then
      gpu_id="gpu${BASH_REMATCH[1]}"
    fi
    if [[ "$line" =~ hashrate_th_s=([0-9]+([.][0-9]*)?) ]]; then
      val="${BASH_REMATCH[1]}"
      if [[ -n "$gpu_id" ]]; then
        GPU_SUM[$gpu_id]="$val"
      else
        sum="$val"
      fi
    fi
    now=$(date +%s)
    if (( now - last_report >= REPORT_INTERVAL )); then
      _flush_hr
      last_report=$now
    fi
  done
  _flush_hr
}

echo "Pearl: worker=${STRATUM_WORKER}  log=${LOG}" >&2
echo "  HR → stratum://${STRATUM_HOST}:${STRATUM_PORT} (pearl.report_hashrate)" >&2
echo "  1 GPU: HR на ${STRATUM_WORKER} и .gpu0 · multi-GPU: только .gpu0 …" >&2

: >"$LOG"

tail -n0 -f "$LOG" | _tail_and_hr &
TAIL_PID=$!
_cleanup() { kill "$TAIL_PID" 2>/dev/null || true; wait "$TAIL_PID" 2>/dev/null || true; }
trap _cleanup EXIT INT TERM

if command -v stdbuf >/dev/null 2>&1; then
  stdbuf -oL -eL "$MINER" "${MINER_ARGS[@]}" >>"$LOG" 2>&1
else
  "$MINER" "${MINER_ARGS[@]}" >>"$LOG" 2>&1
fi
RC=$?
_cleanup
exit "$RC"
