#!/usr/bin/env bash
# scripts/test-default-perms.sh
#
# Snapshot the things that influence what a default-rank player on
# racked.ru can do. Designed for diffing across config changes.
#
# Output: a deterministic dump (sorted where possible) of:
#   - LuckPerms `default` group nodes
#   - ProAntiTab `default` group whitelist
#   - PAT global command whitelist
#   - Plugin enable order from the most recent boot
#   - Aliases defined in commands.yml
#
# Runs from the host (laptop or nullstone). Reads files out of the
# minecraft-mc container; parses YAML / JSON on the host (PyYAML and
# python3 are not present in the Paper container image).
#
# Usage (from any host with SSH access to nullstone):
#   bash scripts/test-default-perms.sh > snapshot.txt
#   bash scripts/test-default-perms.sh --remote > snapshot.txt   # explicit ssh
#
# Then `diff` two snapshots taken before/after a change.
#
# Pairs with docs/PLAYER-SMOKE-TEST.md.

set -euo pipefail

CONTAINER="${MC_CONTAINER:-minecraft-mc}"
DATA="${MC_DATA:-/data}"
SSH_TARGET="${MC_SSH:-user@192.168.0.100}"

# If we're running on the box itself (docker is local), skip SSH.
mode="local"
if ! command -v docker >/dev/null 2>&1 || ! docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$CONTAINER"; then
  mode="ssh"
fi
if [[ "${1:-}" == "--remote" ]]; then
  mode="ssh"
fi

# read_file <path-inside-container>  ->  stdout = file contents
read_file() {
  local path="$1"
  if [[ "$mode" == "ssh" ]]; then
    ssh -o BatchMode=yes "$SSH_TARGET" "docker exec $CONTAINER cat $path"
  else
    docker exec "$CONTAINER" cat "$path"
  fi
}

# rcon <command>  ->  stdout = response (LP exports go to file, not stdout)
rcon() {
  local cmd="$1"
  if [[ "$mode" == "ssh" ]]; then
    ssh -o BatchMode=yes "$SSH_TARGET" "echo '$cmd' | docker exec -i $CONTAINER rcon-cli"
  else
    echo "$cmd" | docker exec -i "$CONTAINER" rcon-cli
  fi
}

# docker_logs  ->  stdout = full container log
docker_logs() {
  if [[ "$mode" == "ssh" ]]; then
    ssh -o BatchMode=yes "$SSH_TARGET" "docker logs $CONTAINER 2>&1"
  else
    docker logs "$CONTAINER" 2>&1
  fi
}

# read_lp_export -> stdout = JSON (decompressed) of latest snapshot
read_lp_export() {
  rcon 'lp export default-perms-snapshot' >/dev/null
  sleep 1
  local path="${DATA}/plugins/LuckPerms/default-perms-snapshot.json.gz"
  if [[ "$mode" == "ssh" ]]; then
    ssh -o BatchMode=yes "$SSH_TARGET" "docker exec $CONTAINER bash -c 'gunzip -c $path'"
  else
    docker exec "$CONTAINER" bash -c "gunzip -c $path"
  fi
}

heading() {
  printf '\n========== %s ==========\n' "$1"
}

heading "Mode"
echo "$mode (target: ${SSH_TARGET}, container: ${CONTAINER})"

# ---------- LuckPerms default-group export ----------
heading "LuckPerms default-group nodes"
read_lp_export | python3 -c '
import json, sys
try:
    data = json.load(sys.stdin)
except Exception as e:
    print(f"(failed to parse LP export: {e})")
    sys.exit(0)
default = data.get("groups", {}).get("default", {}).get("nodes", [])
for node in sorted(default, key=lambda n: (n.get("type",""), n.get("key",""))):
    t = node.get("type","?")
    k = node.get("key","?")
    v = node.get("value","?")
    print(f"{t:12s} {k} = {v}")
'

# ---------- ProAntiTab whitelist ----------
heading "ProAntiTab — global commands"
read_file "${DATA}/plugins/ProAntiTab/storage.yml" | python3 -c '
import sys, yaml
data = yaml.safe_load(sys.stdin) or {}
for cmd in sorted(data.get("global", {}).get("commands", []) or []):
    print(cmd)
'

heading "ProAntiTab — default-group commands"
read_file "${DATA}/plugins/ProAntiTab/storage.yml" | python3 -c '
import sys, yaml
data = yaml.safe_load(sys.stdin) or {}
default = (data.get("groups", {}) or {}).get("default", {}) or {}
priority = default.get("priority", "?")
print("# priority: " + str(priority))
for cmd in sorted(default.get("commands", []) or []):
    print(cmd)
'

# ---------- commands.yml aliases ----------
heading "commands.yml aliases"
read_file "${DATA}/commands.yml" | python3 -c '
import sys, yaml
data = yaml.safe_load(sys.stdin) or {}
aliases = data.get("aliases", {}) or {}
for name in sorted(aliases.keys()):
    target = aliases[name]
    print(f"{name}: {target}")
'

# ---------- Plugin enable order (latest boot) ----------
heading "Plugin enable order — latest boot"
docker_logs \
  | grep -E "Enabling [A-Z]" \
  | tail -25 \
  | sed -E 's/^\[[0-9:]+\] \[Server thread\/INFO\]: //'

heading "Snapshot complete: $(date -Is)"
