#!/usr/bin/env bash
# orca-drift-notify.sh — peer-side drift event recorder (P10b, REQ-106).
#
# Invoked by systemd Path units (orca-drift-<name>.service) when a
# critical path changes. Receives the changed path as $1 (from systemd
# %f). Computes sha256sum of the file (or "DELETED" if absent), reads
# the latest applied txn from /etc/orca/state/latest-applied-txn, and
# writes an event JSON to /etc/orca/state/drift-events/<event-id>.json.
# Uses flock for serialization. R-001-clean: pure bash + sha256sum.
#
# Usage: orca-drift-notify.sh <path>
#
# Exit codes: 0 = event recorded; 1 = bad args / write failure.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/orca-log.sh
. "$SCRIPT_DIR/lib/orca-log.sh"

ORCA_LOG_ACTOR="spiffe://orca/cli/drift-notify"

STATE_DIR="${ORCA_STATE_DIR:-/etc/orca/state}"
EVENTS_DIR="$STATE_DIR/drift-events"
LATEST_TXN_FILE="$STATE_DIR/latest-applied-txn"
LOCK_FILE="$STATE_DIR/drift-events.lock"

if [ "$#" -lt 1 ]; then
	orca_log_error "drift-notify" "-" "failed" "missing path argument"
	echo "usage: orca-drift-notify.sh <path>" >&2
	exit 1
fi

PATH_ARG="$1"

mkdir -p "$EVENTS_DIR"

compute_sha() {
	local p="$1"
	if [ ! -e "$p" ]; then
		echo "DELETED"
		return
	fi
	sha256sum "$p" 2>/dev/null | awk '{print $1}' || echo "ERROR"
}

read_latest_txn() {
	if [ -f "$LATEST_TXN_FILE" ]; then
		cat "$LATEST_TXN_FILE" 2>/dev/null || true
	fi
}

gen_event_id() {
	local ts_us random_suffix
	ts_us="$(date -u +%Y%m%d%H%M%S%6N)"
	random_suffix="$(head -c 4 /dev/urandom 2>/dev/null | od -An -tx1 | tr -d ' \n' || echo "0000")"
	echo "EVT-${ts_us}-${random_suffix}"
}

NEW_SHA="$(compute_sha "$PATH_ARG")"
LATEST_TXN="$(read_latest_txn || true)"
EVENT_ID="$(gen_event_id)"
TS="$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)"
HOST="$(hostname 2>/dev/null || echo unknown)"

if [ "$NEW_SHA" = "DELETED" ]; then
	STATUS="deleted"
elif [ ! -f "$PATH_ARG" ]; then
	STATUS="created"
else
	STATUS="modified"
fi

escape_json() {
	local s="$1"
	s="${s//\\/\\\\}"
	s="${s//\"/\\\"}"
	printf '%s' "$s"
}

PATH_ESC="$(escape_json "$PATH_ARG")"
HOST_ESC="$(escape_json "$HOST")"

EVENT_JSON=$(cat <<JSON
{"event_id":"$EVENT_ID","ts":"$TS","host":"$HOST_ESC","path":"$PATH_ESC","status":"$STATUS","new_sha256":"$NEW_SHA","latest_txn":"$LATEST_TXN","drift_confirmed":false,"action":"reported","action_result":"skipped"}
JSON
)

EVENT_FILE="$EVENTS_DIR/${EVENT_ID}.json"

(
	flock 9 || { orca_log_error "drift-notify" "$PATH_ARG" "failed" "flock"; exit 1; }
	printf '%s\n' "$EVENT_JSON" >"$EVENT_FILE.tmp"
	mv "$EVENT_FILE.tmp" "$EVENT_FILE"
) 9>"$LOCK_FILE"

orca_log_info "drift-notify" "$PATH_ARG" "ok" "event=$EVENT_ID status=$STATUS sha=$NEW_SHA"
echo "event=$EVENT_ID"
exit 0
