#!/usr/bin/env bash
# scripts/restic-init.sh
#
# One-time bootstrap for the Phase 2 restic backup chain. Run this on
# nullstone as root (sudo) AFTER `apt install restic mcrcon`.
#
# What it does:
#   1. Generates /etc/mc-backup.pw (40-byte random restic password) if absent.
#   2. Writes /etc/mc-backup.env (consumed by restic-backup-playerdata.sh).
#   3. Initialises the local restic repo at /home/user/restic/mc-frequent.
#   4. Takes a baseline snapshot so the timer's first run is fast.
#   5. Optionally adds an SFTP-mirror block once onyx is provisioned.
#
# Idempotent — re-running is safe; existing files are preserved.
#
# Cross-ref: docs/BACKUP-STRATEGY.md §8.2, docs/RUNBOOK-BACKUP-RESTORE.md.
set -euo pipefail
umask 077

if [ "$(id -u)" -ne 0 ]; then
    echo "FATAL: must run as root (sudo)." >&2
    exit 2
fi

if ! command -v restic >/dev/null 2>&1; then
    echo "FATAL: restic not installed. Run: apt install restic mcrcon" >&2
    exit 3
fi

# Resolve target user — restic repo lives under their home so /opt
# disk pressure doesn't matter. nullstone: 142G free on /home.
TARGET_USER="${TARGET_USER:-user}"
if ! id "$TARGET_USER" >/dev/null 2>&1; then
    echo "FATAL: user '$TARGET_USER' not found" >&2
    exit 4
fi
TARGET_HOME=$(getent passwd "$TARGET_USER" | cut -d: -f6)

PW_FILE="/etc/mc-backup.pw"
ENV_FILE="/etc/mc-backup.env"
REPO_FREQUENT="${TARGET_HOME}/restic/mc-frequent"
REPO_WORLD="${TARGET_HOME}/restic/mc-world"
LOG_DIR="/var/log"
SENTINEL_DIR="/var/lib/mc-backup"

# 1. Password file
if [ ! -e "$PW_FILE" ]; then
    head -c 40 /dev/urandom | base64 > "$PW_FILE"
    chown root:root "$PW_FILE"
    chmod 600 "$PW_FILE"
    echo "Generated $PW_FILE (40 bytes random)."
else
    echo "$PW_FILE already exists — keeping."
fi

# 2. Env file (only created if missing; user can edit afterwards).
if [ ! -e "$ENV_FILE" ]; then
    cat > "$ENV_FILE" <<EOF
# /etc/mc-backup.env — consumed by restic-backup-playerdata.sh and the
# Class B/C/D world script (TBD). Edit as needed.

RESTIC_REPOSITORY_FREQUENT=$REPO_FREQUENT
RESTIC_REPOSITORY_WORLD=$REPO_WORLD
RESTIC_PASSWORD_FILE=$PW_FILE
MC_DATA=/opt/docker/minecraft
MC_BACKUP_LOG=$LOG_DIR/mc-backup.log
MC_BACKUP_FREQUENT_SENTINEL=$SENTINEL_DIR/last-success-frequent
MC_BACKUP_WORLD_SENTINEL=$SENTINEL_DIR/last-success-world

# RCON — used to flush MC saves before snapshotting. Pull from the live
# compose file (services.mc.environment.RCON_PASSWORD).
MC_RCON_HOST=127.0.0.1
MC_RCON_PORT=25575
MC_RCON_PASSWORD=${MC_RCON_PASSWORD}

# Off-host mirror destination (onyx via Tailscale). Empty = skip mirror.
TS_OFFHOST_USER=mc-backup
TS_OFFHOST_HOST=100.64.0.1
TS_OFFHOST_PATH=/backups/nullstone-mc-restic

# Alerting — fill in once ntfy.s8n.ru is up. Leave blank for now.
HEARTBEAT_URL=
ALERT_URL=
EOF
    chown root:"$(id -gn "$TARGET_USER")" "$ENV_FILE"
    chmod 640 "$ENV_FILE"
    echo "Wrote $ENV_FILE (mode 640, group=$(id -gn "$TARGET_USER"))."
else
    echo "$ENV_FILE already exists — keeping."
fi

# 3. Log + sentinel dirs (writable by target user).
mkdir -p "$SENTINEL_DIR"
chown "$TARGET_USER":"$(id -gn "$TARGET_USER")" "$SENTINEL_DIR"
chmod 750 "$SENTINEL_DIR"
touch "$LOG_DIR/mc-backup.log"
chown "$TARGET_USER":adm "$LOG_DIR/mc-backup.log" 2>/dev/null \
    || chown "$TARGET_USER":"$(id -gn "$TARGET_USER")" "$LOG_DIR/mc-backup.log"
chmod 640 "$LOG_DIR/mc-backup.log"

# 4. Repo init (idempotent — restic init exits non-zero if repo exists).
init_repo() {
    local repo=$1
    install -d -o "$TARGET_USER" -g "$(id -gn "$TARGET_USER")" -m 700 \
        "$(dirname "$repo")" "$repo"
    if RESTIC_PASSWORD_FILE="$PW_FILE" RESTIC_REPOSITORY="$repo" \
        runuser -u "$TARGET_USER" -- restic snapshots >/dev/null 2>&1; then
        echo "Repo $repo: already initialised."
    else
        RESTIC_PASSWORD_FILE="$PW_FILE" RESTIC_REPOSITORY="$repo" \
            runuser -u "$TARGET_USER" -- restic init
        echo "Repo $repo: initialised."
    fi
}
init_repo "$REPO_FREQUENT"
init_repo "$REPO_WORLD"

# 5. Baseline snapshot of the frequent repo so the first timer run is fast.
echo "Taking baseline snapshot into $REPO_FREQUENT ..."
runuser -u "$TARGET_USER" -- env \
    RESTIC_PASSWORD_FILE="$PW_FILE" \
    RESTIC_REPOSITORY="$REPO_FREQUENT" \
    restic backup \
        --tag playerdata --tag baseline --host "$(hostname)" \
        --exclude='*.lock' --exclude='*.tmp' \
        /opt/docker/minecraft/world/playerdata \
        /opt/docker/minecraft/world/stats \
        /opt/docker/minecraft/world/advancements \
        /opt/docker/minecraft/homestead_data.db \
        /opt/docker/minecraft/plugins/AuthMe \
        /opt/docker/minecraft/plugins/CoreProtect/database.db \
        /opt/docker/minecraft/plugins/LuckPerms \
    || echo "Baseline snapshot returned non-zero — review output above."

cat <<'NEXT'

  ---------------------------------------------------------------
  restic-init.sh complete.

  Next steps:
    1. Install systemd units:
         install -m644 scripts/systemd/mc-backup-playerdata.service \
                       /etc/systemd/system/
         install -m644 scripts/systemd/mc-backup-playerdata.timer \
                       /etc/systemd/system/
         install -m755 scripts/restic-backup-playerdata.sh \
                       /usr/local/bin/

    2. systemctl daemon-reload
    3. systemctl enable --now mc-backup-playerdata.timer
    4. Tail: journalctl -u mc-backup-playerdata.service -f

  Onyx (off-host mirror) provisioning is a separate step — see
  docs/RUNBOOK-BACKUP-RESTORE.md "Phase 2 deployment".
  ---------------------------------------------------------------
NEXT
