#!/bin/sh
set -eu
umask 077

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
PUBLIC="$BASE/public"
PUBLIC_BASE="${ROUTER_PUBLIC_BASE_URL:-https://reports.secret-studio.ru}"
PUBLIC_BASE="${PUBLIC_BASE%/}"
TOKEN_FILE="${ROUTER_PUBLIC_TOKEN_FILE:-$PUBLIC/.router-public-token}"
TOKEN="${ROUTER_PUBLIC_TOKEN:-}"

if [ -z "$TOKEN" ]; then
  TOKEN="$(cat "$TOKEN_FILE")"
fi

ROOT="${ROUTER_PUBLIC_ROOT:-$PUBLIC/r/$TOKEN}"
LATEST="$ROOT/latest"
OLD="$ROOT/old"
REINDEX="${ROUTER_PUBLIC_REINDEX:-$BASE/bin/router-public-reindex}"
LOCK_DIR="$BASE/state/locks"
LOCK_FILE="$LOCK_DIR/public-publish.lock"

if [ "$#" -lt 2 ]; then
  echo "Usage: router-publish-report <label> <file1> [file2 ...]" >&2
  exit 1
fi

LABEL_RAW="$1"
shift

LABEL="$(printf '%s' "$LABEL_RAW" | tr -c 'A-Za-z0-9_.-' '_' | sed 's/__*/_/g; s/^_//; s/_$//')"
[ -n "$LABEL" ] || LABEL="report"
LABEL_LOWER="$(printf '%s' "$LABEL" | tr '[:upper:]' '[:lower:]')"

case "$LABEL_LOWER" in
  vm100_git_source_*) KIND="vm100"; MATCH='*_vm100_git_source_*' ;;
  vm101_git_source_*) KIND="vm101"; MATCH='*_vm101_git_source_*' ;;
  vm121_git_source_*) KIND="vm121"; MATCH='*_vm121_git_source_*' ;;
  local_architecture_plan_vm101_autonomous_hmn_recovery*) KIND="local-m07-plan"; MATCH='*_local_architecture_plan_vm101_autonomous_hmn_recovery*' ;;
  global_project_plan_wg_paid*) KIND="global-project-plan"; MATCH='*_global_project_plan_wg_paid*' ;;
  xs_map_*|access_map_*) KIND="access-map"; MATCH='access-map-special' ;;
  vm101_model_*) KIND="vm101-model"; MATCH='*_vm101_model_*' ;;
  vm101_methods_*) KIND="vm101-methods"; MATCH='*_vm101_methods_*' ;;
  vm130_router_ops_source_snapshot*) KIND="vm130-source"; MATCH='*_vm130_router_ops_source_snapshot*' ;;
  step*|*_step*) KIND="step-report"; MATCH='*_step*' ;;
  *) KIND="label:$LABEL"; MATCH="*_${LABEL}" ;;
esac

TS="$(date -u +%Y%m%d-%H%M%S)"
FOLDER="${TS}_${LABEL}"
STAGE_ROOT="$(mktemp -d "$BASE/state/public-publish-stage.${TS}.XXXXXX")"
STAGE_DIR="$STAGE_ROOT/$FOLDER"
MOVED_LIST="$STAGE_ROOT/moved-from-latest.txt"
NEW_MOVED=0
COMMITTED=0

cleanup() {
  RC=$?
  trap - EXIT INT TERM HUP
  set +e

  if [ "$COMMITTED" -ne 1 ]; then
    if [ "$NEW_MOVED" -eq 1 ] && [ -d "$LATEST/$FOLDER" ]; then
      mv "$LATEST/$FOLDER" "$STAGE_DIR"
    fi

    if [ -s "$MOVED_LIST" ]; then
      tac "$MOVED_LIST" | while IFS= read -r NAME; do
        [ -n "$NAME" ] || continue
        if [ -d "$OLD/$NAME" ] && [ ! -e "$LATEST/$NAME" ]; then
          mv "$OLD/$NAME" "$LATEST/$NAME"
        fi
      done
    fi

    "$REINDEX" >/dev/null 2>&1 || true
  fi

  rm -rf "$STAGE_ROOT"
  exit "$RC"
}
trap cleanup EXIT INT TERM HUP

mkdir -p "$LATEST" "$OLD" "$LOCK_DIR" "$STAGE_DIR"
chmod 755 "$ROOT" "$LATEST" "$OLD" "$STAGE_DIR"
: > "$MOVED_LIST"

exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "ERROR: another publication is running" >&2
  exit 1
fi

REFUSE_RE='raw|\.env|secret|secrets|private|Private|id_rsa|id_ed25519|authorized_keys|wg[0-9]?.conf|amnezia|hmn.*code|access.*code'

for SRC in "$@"; do
  if [ ! -f "$SRC" ]; then
    echo "ERROR: file not found: $SRC" >&2
    exit 1
  fi

  BASESRC="$(basename "$SRC")"

  if printf '%s\n%s\n' "$SRC" "$BASESRC" | grep -Eiq "$REFUSE_RE"; then
    echo "REFUSE: suspicious path/name, not publishing: $SRC" >&2
    exit 2
  fi

  cp -a "$SRC" "$STAGE_DIR/$BASESRC"
  chmod 644 "$STAGE_DIR/$BASESRC"
done

{
  echo '<!doctype html><html><head><meta charset="utf-8"><title>router report</title></head><body>'
  printf '<h1>%s %s</h1>\n' "$TS" "$LABEL"
  echo '<ul>'
  find "$STAGE_DIR" -maxdepth 1 -type f | LC_ALL=C sort | while IFS= read -r FILE; do
    NAME="$(basename "$FILE")"
    printf '<li><a href="%s">%s</a></li>\n' "$NAME" "$NAME"
  done
  echo '</ul>'
  echo '<p><a href="../">Back to latest</a></p>'
  echo '</body></html>'
} > "$STAGE_DIR/index.html"
chmod 644 "$STAGE_DIR/index.html"

if [ "$KIND" = "access-map" ]; then
  find "$LATEST" \
    -mindepth 1 \
    -maxdepth 1 \
    -type d \
    \( -name '*_xs_map_*' -o -name '*_access_map_*' \) \
    -printf '%f\n'
else
  find "$LATEST" \
    -mindepth 1 \
    -maxdepth 1 \
    -type d \
    -name "$MATCH" \
    -printf '%f\n'
fi |
LC_ALL=C sort |
while IFS= read -r NAME; do
  [ -n "$NAME" ] || continue
  if [ -e "$OLD/$NAME" ]; then
    echo "ERROR: historical destination already exists: $OLD/$NAME" >&2
    exit 1
  fi
  mv "$LATEST/$NAME" "$OLD/$NAME"
  printf '%s\n' "$NAME" >> "$MOVED_LIST"
done

if [ -e "$LATEST/$FOLDER" ]; then
  echo "ERROR: publication destination already exists: $LATEST/$FOLDER" >&2
  exit 1
fi

mv "$STAGE_DIR" "$LATEST/$FOLDER"
NEW_MOVED=1

"$REINDEX" >/dev/null

TRYCF_BASE="${TUNNEL_BASE:-}"
if [ -z "$TRYCF_BASE" ] && [ -f "$BASE/state/current-quick-tunnel.env" ]; then
  TRYCF_BASE="$(awk -F= '$1=="QUICK_TUNNEL_URL" {print substr($0,index($0,"=")+1)}' "$BASE/state/current-quick-tunnel.env" | tail -n 1)"
fi
if [ -z "$TRYCF_BASE" ] && [ -f "$PUBLIC/cloudflared-quick.log" ]; then
  TRYCF_BASE="$(grep -Eo 'https://[-a-zA-Z0-9.]+\.trycloudflare\.com' "$PUBLIC/cloudflared-quick.log" | tail -n 1 || true)"
fi

PREVIOUS_MOVED_COUNT="$(awk 'END {print NR + 0}' "$MOVED_LIST")"
COMMITTED=1
trap - EXIT INT TERM HUP
rm -rf "$STAGE_ROOT"

PUBLISHED_DIR="$LATEST/$FOLDER"
PUBLISHED_RELATIVE_PATH="latest/$FOLDER"

printf 'PUBLISHED_DIR=%s\n' "$PUBLISHED_DIR"
printf 'PUBLISHED_RELATIVE_PATH=%s\n' "$PUBLISHED_RELATIVE_PATH"
printf 'PUBLIC_OBJECT_KIND=%s\n' "$KIND"
printf 'PREVIOUS_MOVED_COUNT=%s\n' "$PREVIOUS_MOVED_COUNT"
printf 'LOCAL_INDEX=http://192.168.30.84:8099/r/%s/latest/%s/\n' "$TOKEN" "$FOLDER"
printf 'LATEST_ROOT_URL=%s/latest/\n' "$PUBLIC_BASE"
printf 'OLD_ROOT_URL=%s/old/\n' "$PUBLIC_BASE"
printf 'PUBLIC_INDEX=%s/latest/\n' "$PUBLIC_BASE"
printf 'PUBLIC_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"

case "$KIND" in
  step-report)
    printf 'STEP_REPORT_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  local-m07-plan)
    printf 'LOCAL_M07_PLAN_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  global-project-plan)
    printf 'GLOBAL_PROJECT_PLAN_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  access-map)
    printf 'ACCESS_MAP_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm100)
    printf 'VM100_PUBLIC_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm101)
    printf 'VM101_PUBLIC_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm121)
    printf 'VM121_PUBLIC_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm101-model)
    printf 'VM101_MODEL_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm101-methods)
    printf 'VM101_METHODS_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
  vm130-source)
    printf 'VM130_SOURCE_URL=%s/latest/%s/\n' "$PUBLIC_BASE" "$FOLDER"
    ;;
esac

if [ -n "$TRYCF_BASE" ]; then
  TRYCF_BASE="${TRYCF_BASE%/}"
  printf 'TRYCF_INDEX=%s/r/%s/latest/\n' "$TRYCF_BASE" "$TOKEN"
  printf 'TRYCF_REPORT=%s/r/%s/latest/%s/\n' "$TRYCF_BASE" "$TOKEN" "$FOLDER"
fi
