#!/bin/sh
set -eu
umask 077

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
PUBLIC="$BASE/public"
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='*_xs_map_*' ;;
  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"

find "$LATEST" \
  -mindepth 1 \
  -maxdepth 1 \
  -type d \
  -name "$MATCH" \
  -printf '%f\n' |
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"

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
