#!/bin/bash
# tgstat-puller: обёртка вокруг pull.py, которая держит клон волта в чистоте.
#
# Зачем она вообще есть. pull.py пишет в волт две вещи: архив постов личного
# канала (перезаписывается целиком) и снапшоты просмотров (дописываются).
# На Pi волт — git-клон, и до этой обёртки прогон 07:00 оставлял дерево
# грязным. Дальше `git pull --rebase` при незакоммиченных изменениях
# отказывается работать даже по несвязанным файлам (rebase.autoStash в клоне
# не выставлен), и по цепочке падали все, кто тянет волт после: feedwatch
# (07:15), enwatch (07:30) и утренний прогон (08:15). Утро при этом молча
# уходило на вчерашнем состоянии волта — свежие транскрипты митингов,
# приезжающие с Мака в 08:20, не попадали в него вообще.
#
# Поэтому здесь тот же git-блок, что у соседей (enwatch.sh, trendwatch.sh,
# feedwatch/nisha.sh, morning.sh): pull --rebase до прогона, add + commit +
# push после, `rebase --abort` при неудаче, чтобы не оставить клон в
# полурасплавленном состоянии.
#
# Логи идут в stdout/stderr, то есть в journald: там же живёт вывод самого
# pull.py, и разносить их по двум местам незачем (journalctl -u tgstat-pull).
#
# Включается флагом TGSTAT_GIT_SYNC=1 в .env (на Маке волт не клон — там
# флага нет, и обёртка просто зовёт pull.py).
# Запуск: bash pull.sh [аргументы pull.py]
set -u

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
[ -f "$SCRIPT_DIR/.env" ] && { set -a; source "$SCRIPT_DIR/.env"; set +a; }

VAULT="${TGSTAT_VAULT_ROOT:-}"
GIT_SYNC="${TGSTAT_GIT_SYNC:-0}"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] pull.sh: $*"; }

# Синк включён только когда есть и флаг, и настоящий клон: иначе каждый
# git-вызов будет ругаться в журнал, а причина останется неочевидной.
git_sync_on() {
  [ "$GIT_SYNC" = "1" ] || return 1
  if [ -z "$VAULT" ] || [ ! -d "$VAULT/.git" ]; then
    log "WARN: TGSTAT_GIT_SYNC=1, но волт «$VAULT» не git-клон — синк пропущен"
    return 1
  fi
  return 0
}

if git_sync_on; then
  if ! git -C "$VAULT" pull --rebase; then
    git -C "$VAULT" rebase --abort >/dev/null 2>&1
    log "WARN: git pull --rebase не прошёл (конфликт) — откатил rebase, работаю на локальном состоянии волта"
  fi
fi

"$SCRIPT_DIR/venv/bin/python" "$SCRIPT_DIR/pull.py" "$@"
RC=$?
log "pull.py rc=$RC"

# Ровно то, что пишет прогон, и ничего больше. `git add projects/channel`
# целиком захватил бы рукописный канон (agents.md, контент-календарь, сетку
# рубрик, бэклог, tasks.md) — он в том же каталоге.
VAULT_PATHS=(
  "projects/channel/{channel} {source} TGStat архив постов канала.json"
  "projects/channel/{channel} {source} TGStat архив постов канала.md"
  "projects/channel/{channel} {source} снапшоты просмотров.jsonl"
  "projects/mars/tgstat-snapshots"
)

push_vault() {
  git_sync_on || return 0

  # Пути добавляем по одному: `git add a b` при отсутствующем `a` падает на
  # pathspec и не добавляет ничего, включая существующие пути. А отсутствие
  # части путей — штатный случай: прогон с --channel natashhhh не трогает
  # каталог Mars-каналов вовсе.
  local p
  for p in "${VAULT_PATHS[@]}"; do
    git -C "$VAULT" add -- "$p" 2>/dev/null || true
  done

  if ! git -C "$VAULT" commit -m "tgstat-puller: архив и снапшоты $(date +%Y-%m-%d)"; then
    log "git: коммитить нечего"
    return 0
  fi

  local attempt
  for attempt in 1 2 3; do
    if git -C "$VAULT" push; then
      [ "$attempt" -gt 1 ] && log "git: push прошёл с попытки $attempt"
      return 0
    fi
    log "WARN: push не прошёл (попытка $attempt) — тяну волт и пробую снова"
    if ! git -C "$VAULT" pull --rebase; then
      git -C "$VAULT" rebase --abort >/dev/null 2>&1
      log "ERROR: pull --rebase не прошёл — коммит остаётся локальным"
      return 0
    fi
    sleep 3
  done
  log "ERROR: push не прошёл после 3 попыток — коммит остаётся локальным"
  return 0
}

push_vault
exit $RC
