#!/usr/bin/env bash
# Run Godot handler tests via MCP in CI.
# Expects: Python server running on port 8000, Godot editor launched with plugin.
# This script waits for the plugin to connect before running tests.
set -euo pipefail
source "$(dirname "$0")/_ci_env.sh"

SERVER_URL="http://127.0.0.1:8000/mcp"
HEADERS=(-H "Content-Type: application/json" -H "Accept: application/json, text/event-stream")

# Wait for Godot plugin to connect (session_manage(op="list") returns count > 0)
echo "Waiting for Godot plugin to connect..."
for i in $(seq 1 60); do
  SESSION_ID=$(curl -si "$SERVER_URL" -X POST "${HEADERS[@]}" \
    -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"ci","version":"1.0"}}}' \
    2>&1 | grep -i 'mcp-session-id' | tr -d '\r' | awk '{print $2}')

  if [ -z "$SESSION_ID" ]; then
    sleep 2
    continue
  fi

  curl -s "$SERVER_URL" -X POST "${HEADERS[@]}" \
    -H "Mcp-Session-Id: $SESSION_ID" \
    -d '{"jsonrpc":"2.0","method":"notifications/initialized"}' > /dev/null

  SESSIONS=$(curl -s "$SERVER_URL" -X POST "${HEADERS[@]}" \
    -H "Mcp-Session-Id: $SESSION_ID" \
    -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"session_manage","arguments":{"op":"list"}}}')

  if echo "$SESSIONS" | grep -q '"count":'; then
    COUNT=$(echo "$SESSIONS" | python3 -c "
import json, sys
raw = sys.stdin.read()
for line in raw.split('\n'):
    if line.startswith('data: '):
        data = json.loads(line[6:])
        sc = data.get('result',{}).get('structuredContent',{})
        if not sc:
            text = data.get('result',{}).get('content',[{}])[0].get('text','{}')
            sc = json.loads(text)
        print(sc.get('count', 0))
        break
" 2>/dev/null || echo "0")
    if [ "$COUNT" -gt 0 ] 2>/dev/null; then
      echo "Godot plugin connected (session count: $COUNT)"
      break
    fi
  fi

  echo "  attempt $i — no session yet"
  sleep 2
done

if [ -z "${SESSION_ID:-}" ]; then
  echo "ERROR: Could not connect to MCP server"
  exit 1
fi

# Verify a Godot session is actually connected before running tests
FINAL_COUNT=$(curl -s "$SERVER_URL" -X POST "${HEADERS[@]}" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":99,"method":"tools/call","params":{"name":"session_manage","arguments":{"op":"list"}}}' \
  | python3 -c "
import json, sys
raw = sys.stdin.read()
for line in raw.split('\n'):
    if line.startswith('data: '):
        data = json.loads(line[6:])
        sc = data.get('result',{}).get('structuredContent',{})
        if not sc:
            text = data.get('result',{}).get('content',[{}])[0].get('text','{}')
            sc = json.loads(text)
        print(sc.get('count', 0))
        break
" 2>/dev/null || echo "0")

if [ "$FINAL_COUNT" -eq 0 ] 2>/dev/null; then
  echo "ERROR: No Godot session connected after 60 attempts. Plugin may not have loaded."
  exit 1
fi

# Give the editor time to finish its filesystem scan and script class
# registration. Without this, test_run fires before DirAccess sees the
# test scripts — the plugin connects before the scan completes.
echo "Waiting for editor filesystem scan to settle..."
sleep 8

# Open main.tscn so tests that need a scene root can actually run.
# In a fresh CI checkout there's no editor state, so no scene is open by default.
echo "Opening main.tscn..."
curl -s "$SERVER_URL" -X POST "${HEADERS[@]}" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":10,"method":"tools/call","params":{"name":"scene_open","arguments":{"path":"res://main.tscn"}}}' > /dev/null
sleep 2

# Call test_run
echo "Running handler tests..."
RESULT=$(curl -s "$SERVER_URL" -X POST "${HEADERS[@]}" \
  -H "Mcp-Session-Id: $SESSION_ID" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"test_run","arguments":{}}}')

# Parse and report results
echo "$RESULT" | python3 -c "
import json, sys
raw = sys.stdin.read()
for line in raw.split('\n'):
    if line.startswith('data: '):
        data = json.loads(line[6:])
        content = data.get('result', {}).get('structuredContent', {})
        if not content:
            text = data.get('result', {}).get('content', [{}])[0].get('text', '{}')
            content = json.loads(text)
        passed = content.get('passed', 0)
        failed = content.get('failed', 0)
        total = content.get('total', 0)
        load_errors = content.get('load_errors', []) or []
        print(f'Godot tests: {passed}/{total} passed, {failed} failed')
        if content.get('failures'):
            for f in content['failures']:
                print(f'  FAIL: {f[\"suite\"]}.{f[\"test\"]}: {f[\"message\"]}')
        if load_errors:
            print(f'  LOAD ERRORS: {len(load_errors)} test file(s) failed to parse:')
            for le in load_errors:
                print(f'    - {le}')
        if failed > 0:
            sys.exit(1)
        if load_errors:
            print('ERROR: At least one test file failed to load (parse error?). Treating as failure so silent test-loss does not slip past CI.')
            sys.exit(1)
        if total == 0:
            print('ERROR: No tests ran — Godot plugin may not have connected')
            sys.exit(1)
        break
else:
    print('ERROR: No valid response from test_run')
    print(f'Raw response: {raw[:500]}')
    sys.exit(1)
"
