#!/usr/bin/env bash

## Description: Make a real OAuth MCP tool call and show the governance, gateway and correlation rows it added
## Usage: governance-call [--no-rows] <client_id> <scope> <tool> [json-args]
## Example: "ddev governance-call govok bifrost:read ai_governance_get_my_actions" or "ddev governance-call govok bifrost:read some_tool '{\"x\":1}'"

# Host command, LOCAL DEV SITES ONLY: it resets the consumer's secret to a
# fixed value (MCP_SECRET, default governance-call-local) and replaces its
# client_credentials scopes with <scope> (an oauth2_scope name, e.g.
# bifrost:read). MCP endpoint path: MCP_PATH, default /mcp.
set -euo pipefail

ROWS=1
if [ "${1:-}" = "--no-rows" ]; then ROWS=0; shift; fi
[ $# -ge 3 ] || { echo "Usage: ddev governance-call [--no-rows] <client_id> <scope> <tool> [json-args]" >&2; exit 1; }
case "${DDEV_PRIMARY_URL:-}" in
  https://*.ddev.site|http://*.ddev.site) ;;
  *) echo "Refusing to run outside a local DDEV site (DDEV_PRIMARY_URL='${DDEV_PRIMARY_URL:-}')." >&2; exit 1 ;;
esac

CLIENT=$1 SCOPE=$2 TOOL=$3 ARGS=${4:-'{}'}
SECRET=${MCP_SECRET:-governance-call-local}
URL="${DDEV_PRIMARY_URL}${MCP_PATH:-/mcp}"
TABLES="ai_governance_governance_log ai_governance_gateway_log ai_governance_correlation"

declare -A MAX
if [ "$ROWS" = 1 ]; then
  for t in $TABLES; do
    MAX[$t]=$(ddev drush sqlq "SELECT COALESCE(MAX(id), 0) FROM $t")
  done
fi

# Give the consumer a known secret and the requested scope.
ddev drush php:eval "
\$etm = \Drupal::entityTypeManager();
\$c = \$etm->getStorage('consumer')->loadByProperties(['client_id' => '$CLIENT']);
if (!\$c) { fwrite(STDERR, \"No consumer '$CLIENT'.\n\"); exit(1); }
\$s = \$etm->getStorage('oauth2_scope')->loadByProperties(['name' => '$SCOPE']);
if (!\$s) { fwrite(STDERR, \"No oauth2_scope named '$SCOPE'.\n\"); exit(1); }
\$c = reset(\$c);
\$c->set('secret', '$SECRET');
\$c->set('scopes', [['scope_id' => reset(\$s)->id()]]);
\$c->save();
" >/dev/null

TOKEN_JSON=$(curl -sk "$DDEV_PRIMARY_URL/oauth/token" -d grant_type=client_credentials \
  -d client_id="$CLIENT" -d client_secret="$SECRET" --data-urlencode scope="$SCOPE")
TOKEN=$(printf '%s' "$TOKEN_JSON" | python3 -c 'import sys,json;print(json.load(sys.stdin).get("access_token",""))')
[ -n "$TOKEN" ] || { echo "Token request failed: $TOKEN_JSON" >&2; exit 1; }

# initialize -> notifications/initialized -> tools/call, on one session.
H=(-sk -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream')
SID=$(curl "${H[@]}" -D - -o /dev/null "$URL" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"governance-call","version":"1"}}}' \
  | awk 'tolower($1)=="mcp-session-id:"{print $2}' | tr -d '\r')
[ -n "$SID" ] && H+=(-H "Mcp-Session-Id: $SID")
curl "${H[@]}" -o /dev/null "$URL" -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
BODY=$(python3 -c 'import json,sys;print(json.dumps({"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":sys.argv[1],"arguments":json.loads(sys.argv[2])}}))' "$TOOL" "$ARGS")
curl "${H[@]}" "$URL" -d "$BODY"
echo

if [ "$ROWS" = 1 ]; then
  for t in $TABLES; do
    echo "--- $t (new rows)"
    ddev drush sqlq --extra=--table "SELECT * FROM $t WHERE id > ${MAX[$t]}"
  done
fi
