#!/usr/bin/env bash
#
# O7 piloto self-host smoke test.
#
# Drives the daemon binary through the three-op piloto sequence
# (propose_adr → update_ontology_node → move_fsm_state) via the CLI
# surface added in O5. Verifies that every op emits a signed witness
# and that the projected state files exist post-execution.
#
# The flags `--task`, `--no-raw-tools`, and `--phase` are accepted but
# treated as advisory metadata: tool-surface restriction belongs to
# the launcher (Claude Code / agent harness), not this script. The
# env var ONTOREF_OPS_ENFORCE=strict is honoured as a metadata switch
# that surfaces in the summary output.

set -euo pipefail

cd "$(dirname "$0")/.."

# ── argument parsing ────────────────────────────────────────────────────────
TASK="(unset)"
PHASE="Progressive"
NO_RAW_TOOLS="0"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --task)           TASK="$2"; shift 2 ;;
    --task=*)         TASK="${1#*=}"; shift ;;
    --phase)          PHASE="$2"; shift 2 ;;
    --phase=*)        PHASE="${1#*=}"; shift ;;
    --no-raw-tools)   NO_RAW_TOOLS="1"; shift ;;
    *) echo "agent-session-test: unknown arg '$1'" >&2; exit 2 ;;
  esac
done

ENFORCE="${ONTOREF_OPS_ENFORCE:-advisory}"
echo "== O7 piloto self-host smoke test =="
echo "  task=$TASK  phase=$PHASE  no_raw_tools=$NO_RAW_TOOLS  enforce=$ENFORCE"
echo

# ── locate the daemon binary ────────────────────────────────────────────────
BIN=""
for candidate in target/release/ontoref-daemon target/debug/ontoref-daemon \
                 /Volumes/Devel/ontoref/target/release/ontoref-daemon \
                 /Volumes/Devel/ontoref/target/debug/ontoref-daemon; do
  if [[ -x "$candidate" ]]; then BIN="$candidate"; break; fi
done

if [[ -z "$BIN" ]]; then
  echo "build daemon first: just build-daemon  (or  cargo build --release -p ontoref-daemon)" >&2
  exit 3
fi

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
mkdir -p "$TMP/.ontology" "$TMP/adrs" "$TMP/reflection"

SEED_HEX="$(printf '42%.0s' {1..32})"

# ── op 1 — propose_adr ──────────────────────────────────────────────────────
echo "→ op 1/3: propose_adr"
INPUTS_1='{
  "id": "adr-099",
  "slug": "piloto-self-host",
  "title": "Piloto self-host",
  "decision": "Adopt the operations layer for ontoref itself.",
  "ondaod_evaluation": {
    "engaged_tensions": ["ontology-vs-reflection"],
    "synthesis_state": "Realized",
    "motion_direction": "Static"
  }
}'
CONTEXT_1="$(jq -n --arg root "$TMP" --arg seed "$SEED_HEX" \
  '{actor_id: "developer", signing_key_seed_hex: $seed, project_root: $root}')"
WITNESS_1="$("$BIN" --invoke-op propose_adr \
  --invoke-inputs "$INPUTS_1" --invoke-context "$CONTEXT_1")"
echo "$WITNESS_1" | jq -e '.op_id == "propose_adr"' >/dev/null \
  || { echo "propose_adr witness missing op_id"; exit 4; }
[[ -f "$TMP/adrs/adr-099-piloto-self-host.ncl" ]] \
  || { echo "ADR file not written"; exit 5; }
echo "  ✓ witness signed; ADR file written"

# ── op 2 — update_ontology_node ─────────────────────────────────────────────
echo "→ op 2/3: update_ontology_node"
INPUTS_2='{
  "node_id": "piloto-self-host",
  "name": "Piloto Self-Host",
  "description": "Records that ontoref runs itself via the operations layer.",
  "pole": "Yang",
  "level": "Practice"
}'
CORE_SNAPSHOT='{"nodes": [], "edges": []}'
CONTEXT_2="$(jq -n --arg root "$TMP" --arg seed "$SEED_HEX" --argjson core "$CORE_SNAPSHOT" \
  '{actor_id: "developer", signing_key_seed_hex: $seed, project_root: $root, core: $core}')"
WITNESS_2="$("$BIN" --invoke-op update_ontology_node \
  --invoke-inputs "$INPUTS_2" --invoke-context "$CONTEXT_2")"
echo "$WITNESS_2" | jq -e '.op_id == "update_ontology_node"' >/dev/null \
  || { echo "update_ontology_node witness missing op_id"; exit 6; }
[[ -f "$TMP/.ontology/core.ncl" ]] \
  || { echo "core.ncl not written"; exit 7; }
echo "  ✓ witness signed; core.ncl rewritten"

# ── op 3 — move_fsm_state ───────────────────────────────────────────────────
echo "→ op 3/3: move_fsm_state"
INPUTS_3='{ "dimension": "adoption", "new_state": "b" }'
STATE_SNAPSHOT='{
  "dimensions": [
    {
      "id": "adoption",
      "name": "Adoption",
      "description": "Piloto FSM dimension.",
      "current_state": "a",
      "desired_state": "c",
      "horizon": "Weeks",
      "states": [],
      "transitions": [
        { "from": "a", "to": "b", "condition": "ready", "catalyst": "", "blocker": "", "horizon": "Weeks" },
        { "from": "b", "to": "c", "condition": "ready", "catalyst": "", "blocker": "", "horizon": "Weeks" }
      ],
      "coupled_with": []
    }
  ]
}'
CONTEXT_3="$(jq -n --arg root "$TMP" --arg seed "$SEED_HEX" --argjson state "$STATE_SNAPSHOT" \
  '{actor_id: "developer", signing_key_seed_hex: $seed, project_root: $root, state: $state}')"
WITNESS_3="$("$BIN" --invoke-op move_fsm_state \
  --invoke-inputs "$INPUTS_3" --invoke-context "$CONTEXT_3")"
echo "$WITNESS_3" | jq -e '.op_id == "move_fsm_state"' >/dev/null \
  || { echo "move_fsm_state witness missing op_id"; exit 8; }
[[ -f "$TMP/.ontology/state.ncl" ]] \
  || { echo "state.ncl not written"; exit 9; }
grep -q 'current_state = "b"' "$TMP/.ontology/state.ncl" \
  || { echo "state.ncl missing post-mutation current_state"; exit 10; }
echo "  ✓ witness signed; state.ncl shows current_state='b'"

# ── summary ─────────────────────────────────────────────────────────────────
echo
echo "== piloto sequence complete =="
jq -n \
  --argjson w1 "$WITNESS_1" \
  --argjson w2 "$WITNESS_2" \
  --argjson w3 "$WITNESS_3" \
  --arg task "$TASK" \
  --arg phase "$PHASE" \
  --arg enforce "$ENFORCE" \
  '{
    task: $task,
    phase: $phase,
    enforce: $enforce,
    op_ids: [$w1.op_id, $w2.op_id, $w3.op_id],
    witness_shapes: [$w1.witness_shape, $w2.witness_shape, $w3.witness_shape],
    state_roots: [$w1.state_root_hex, $w2.state_root_hex, $w3.state_root_hex],
  }'
