#!/usr/bin/env bash
# hostrepo-status put <HOST> <KIND> [json-file]
# Store one status record (JSON, from the file or stdin) in the bucket at
# status/<HOST>/<KIND>/<UTC>.json, for the status page (hostrepo-statuspage).
# KIND is backup, mirror, drill or replica. Records hold numbers and results,
# never warning text, paths or names from the host.
#
# B2 access, whichever the caller has: B2_ACCOUNT_ID/B2_ACCOUNT_KEY or
# MIRROR_B2_ACCOUNT/MIRROR_B2_KEY; bucket from HOSTREPO_B2_BUCKET or
# RESTIC_REPOSITORY (b2:<bucket>:<HOST>). HOSTREPO_STATUS_ROOT (any rclone
# path) replaces the bucket, for testing.
#
# Never fails its caller: a record that cannot be stored is logged, exit 0.
set -uo pipefail
export LC_ALL=C
[[ "${1:-}" == put && $# -ge 3 ]] || { sed -n '2,12p' "$0" >&2; exit 2; }
HOST="$2"; KIND="$3"; SRC="${4:--}"
log() { printf '%s %s\n' "$(date -u +%FT%TZ)" "hostrepo-status: $*" >&2; }
[[ "$HOST" =~ ^[A-Za-z0-9._-]+$ && "$KIND" =~ ^[a-z]+$ ]] || { log "bad host or kind"; exit 0; }
RCLONE="${RCLONE_BIN:-$(command -v rclone || true)}"
[[ -n "$RCLONE" ]] || { log "rclone missing; record not stored"; exit 0; }
body=$(cat -- "$SRC") || { log "cannot read record"; exit 0; }
command -v jq >/dev/null && ! jq -e . >/dev/null 2>&1 <<<"$body" && { log "record is not JSON; not stored"; exit 0; }
name="$(date -u +%Y%m%dT%H%M%SZ).json"
if [[ -n "${HOSTREPO_STATUS_ROOT:-}" ]]; then
  dest="$HOSTREPO_STATUS_ROOT/$HOST/$KIND/$name"
else
  bucket="${HOSTREPO_B2_BUCKET:-}"
  if [[ -z "$bucket" && "${RESTIC_REPOSITORY:-}" == b2:* ]]; then bucket="${RESTIC_REPOSITORY#b2:}"; bucket="${bucket%%:*}"; fi
  acct="${B2_ACCOUNT_ID:-${MIRROR_B2_ACCOUNT:-}}"; key="${B2_ACCOUNT_KEY:-${MIRROR_B2_KEY:-}}"
  [[ -n "$bucket" && -n "$acct" && -n "$key" ]] || { log "no bucket or B2 key; record not stored"; exit 0; }
  dest="b2:$bucket/status/$HOST/$KIND/$name"
fi
# Uploaded with the native API: SHA-1 checked by B2 on receipt, SHA-256 stored.
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; printf '%s\n' "$body" > "$tmp/$name"
if [[ -n "${HOSTREPO_STATUS_ROOT:-}" ]]; then put() { timeout 120 "$RCLONE" copyto -q "$tmp/$name" "$dest"; }
else put() { timeout 120 "$(dirname "$0")/hostrepo-b2put" "$bucket" "status/$HOST/$KIND" "$tmp/$name"; }; fi
if put; then
  log "stored $KIND record for $HOST"
else
  log "could not store $KIND record for $HOST"
fi
exit 0
