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

############################
# НАСТРОЙКИ
############################

# ЗАМЕНИ на реальную точку монтирования nvme1n1
BASE_DIR="/mnt/nvme1/dataset"

# Путь к python из venv
PYTHON_BIN="${PYTHON_BIN:-$PWD/.venv-sdr/bin/python}"

# Путь к headless скрипту
SCRIPT_PATH="${SCRIPT_PATH:-$PWD/scripts_nn/data_saver_headless.py}"

# Проверка, что каталог реально на nvme1n1
EXPECTED_DEVICE_PREFIX="/dev/nvme1n1"

# Лимиты
PER_FREQ_LIMIT_BYTES=$((3 * 1024 * 1024 * 1024))     # 3 GiB на частоту за запуск
TOTAL_LIMIT_BYTES=$((128 * 1024 * 1024 * 1024))      # общий лимит 512 GiB
CYCLE_SECONDS=36                                # один цикл в час

# Параметры SDR
SAMP_RATE="20e6"
SPLIT_SIZE="400000"
DELAY="0.1"
RF_GAIN="12"
IF_GAIN="30"
BB_GAIN="36"

############################
# ЧАСТОТЫ И SERIAL ИЗ ENV
############################

ORDER=(433 750 915 1200 2400 3300 4500 5200 5800)

declare -A SERIAL
declare -A FREQ_HZ

SERIAL[433]="0000000000000000114864dc382a8e1b"
FREQ_HZ[433]="433000000"

SERIAL[750]="0000000000000000114864dc383d0d1b"
FREQ_HZ[750]="750000000"

SERIAL[868]="000000000000000026a468dc36066b63"
FREQ_HZ[868]="868000000"

SERIAL[915]="000000000000000026a468dc36066b63"
FREQ_HZ[915]="915000000"

SERIAL[1200]="0000000000000000518864dc32660d83"
FREQ_HZ[1200]="1200000000"

SERIAL[2400]="0000000000000000919068dc3437b31f"
FREQ_HZ[2400]="2400000000"

SERIAL[3300]="0000000000000000114864dc325069a3"
FREQ_HZ[3300]="3300000000"

SERIAL[4500]="0000000000000000518864dc33833183"
FREQ_HZ[4500]="4500000000"

SERIAL[5200]="0000000000000000874461dc241c7857"
FREQ_HZ[5200]="5200000000"

SERIAL[5800]="0000000000000000919068dc35781c1f"
FREQ_HZ[5800]="5800000000"

############################
# ВСПОМОГАТЕЛЬНОЕ
############################

log() {
  printf '[%s] %s\n' "$(date '+%F %T')" "$*"
}

dir_size_bytes() {
  local path="$1"
  if [[ -e "$path" ]]; then
    du -sb "$path" 2>/dev/null | awk '{print $1}'
  else
    echo 0
  fi
}

total_size_bytes() {
  dir_size_bytes "$BASE_DIR"
}

ensure_requirements() {
  if [[ ! -x "$PYTHON_BIN" ]]; then
    echo "Не найден python: $PYTHON_BIN" >&2
    exit 1
  fi

  if [[ ! -f "$SCRIPT_PATH" ]]; then
    echo "Не найден script: $SCRIPT_PATH" >&2
    exit 1
  fi

  mkdir -p "$BASE_DIR"

  local dev
  dev="$(df -P "$BASE_DIR" | awk 'NR==2 {print $1}')"

  if [[ "$dev" != ${EXPECTED_DEVICE_PREFIX}* ]]; then
    echo "BASE_DIR=$BASE_DIR сейчас находится на $dev, а ожидался ${EXPECTED_DEVICE_PREFIX}*" >&2
    echo "Исправь BASE_DIR на точку монтирования nvme1n1" >&2
    exit 1
  fi
}

run_one_freq() {
  local band="$1"
  local serial="${SERIAL[$band]}"
  local freq="${FREQ_HZ[$band]}"

  local ts out_dir log_file
  ts="$(date '+%F_%H-%M-%S')"
  out_dir="$BASE_DIR/$band/$ts"
  log_file="$out_dir/run.log"

  mkdir -p "$out_dir"

  log "Старт band=$band serial=$serial freq=$freq dir=$out_dir"

  "$PYTHON_BIN" "$SCRIPT_PATH" \
    --serial "$serial" \
    --freq "$freq" \
    --save-dir "$out_dir" \
    --file-tag "${band}_" \
    --samp-rate "$SAMP_RATE" \
    --split-size "$SPLIT_SIZE" \
    --delay "$DELAY" \
    --rf-gain "$RF_GAIN" \
    --if-gain "$IF_GAIN" \
    --bb-gain "$BB_GAIN" \
    >"$log_file" 2>&1 &

  local pid=$!
  log "PID=$pid"

  while kill -0 "$pid" 2>/dev/null; do
    local cur_dir_size cur_total_size
    cur_dir_size="$(dir_size_bytes "$out_dir")"
    cur_total_size="$(total_size_bytes)"

    if (( cur_total_size >= TOTAL_LIMIT_BYTES )); then
      log "Достигнут общий лимит 512 GiB. Останавливаю PID=$pid"
      kill -TERM "$pid" 2>/dev/null || true
      wait "$pid" 2>/dev/null || true
      return 2
    fi

    if (( cur_dir_size >= PER_FREQ_LIMIT_BYTES )); then
      log "Для band=$band достигнут лимит 3 GiB. Останавливаю PID=$pid"
      kill -TERM "$pid" 2>/dev/null || true

      for _ in {1..10}; do
        if ! kill -0 "$pid" 2>/dev/null; then
          break
        fi
        sleep 1
      done

      if kill -0 "$pid" 2>/dev/null; then
        log "PID=$pid не завершился по TERM, отправляю KILL"
        kill -KILL "$pid" 2>/dev/null || true
      fi

      wait "$pid" 2>/dev/null || true
      break
    fi

    sleep 1
  done

  log "Завершен band=$band, размер=$(du -sh "$out_dir" | awk '{print $1}')"
  return 0
}

main_loop() {
  while true; do
    local total_before cycle_start elapsed sleep_left
    total_before="$(total_size_bytes)"

    if (( total_before >= TOTAL_LIMIT_BYTES )); then
      log "Общий размер уже >= 512 GiB, выхожу"
      break
    fi

    cycle_start="$(date +%s)"
    log "Новый цикл"

    for band in "${ORDER[@]}"; do
      if (( $(total_size_bytes) >= TOTAL_LIMIT_BYTES )); then
        log "Общий лимит достигнут внутри цикла, выхожу"
        return 0
      fi

      run_one_freq "$band" || {
        rc=$?
        if [[ $rc -eq 2 ]]; then
          log "Остановка по общему лимиту"
          return 0
        fi
      }
    done

    elapsed=$(( $(date +%s) - cycle_start ))
    sleep_left=$(( CYCLE_SECONDS - elapsed ))

    if (( sleep_left > 0 )); then
      log "Цикл занял ${elapsed} сек, жду ${sleep_left} сек до следующего часа"
      sleep "$sleep_left"
    else
      log "Цикл занял ${elapsed} сек, паузы нет"
    fi
  done
}

ensure_requirements
main_loop