#!/bin/bash
# Analyze telemetry from a harness run.
# Usage: bash analyze-telemetry.sh [command-name]
# Example: bash analyze-telemetry.sh greenfield
#
# Reads .forge/state/telemetry.jsonl and reports:
# 1. Which skills were called (and how many times)
# 2. Which agents were dispatched
# 3. If a command name is given, compares against expected skills

set -euo pipefail

PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
TELEMETRY_FILE="$PROJECT_ROOT/.forge/state/telemetry.jsonl"

if [ ! -f "$TELEMETRY_FILE" ]; then
  echo "No telemetry file found at $TELEMETRY_FILE"
  echo "Run a command first to generate telemetry."
  exit 1
fi

COMMAND="${1:-}"
# Normalize: accept "/dream" as well as "dream"; case-insensitive so "Dream" matches.
COMMAND="${COMMAND#/}"
COMMAND="$(printf '%s' "$COMMAND" | tr '[:upper:]' '[:lower:]')"

echo "=== TELEMETRY ANALYSIS ==="
echo ""

echo "## Skills Called"
jq -r 'select(.type == "skill") | .name' "$TELEMETRY_FILE" | sort | uniq -c | sort -rn
echo ""

echo "## Agents Dispatched"
jq -r 'select(.type == "agent") | "\(.name) — \(.description)"' "$TELEMETRY_FILE" | sort | uniq -c | sort -rn
echo ""

echo "## Timeline"
jq -r '"\(.timestamp) [\(.type)] \(.name)"' "$TELEMETRY_FILE"
echo ""

# Expected skills per command
if [ -n "$COMMAND" ]; then
  echo "## Compliance Check: /$COMMAND"
  echo ""

  case "$COMMAND" in
    greenfield)
      # discover-requirements is conditional (substantive existing requirements docs only).
      # plan-design-system is conditional (skipped for backend-only/CLI projects without a frontend).
      # quality-uiux is conditional (frontend projects only).
      EXPECTED_SKILLS="discover-requirements concept-slides build-wireframe plan-design-system build-prototype iterate-prototype harden build-tdd quality-code-review quality-test-plan quality-test-execution quality-uiux build-pr-workflow support-gotcha"
      EXPECTED_AGENTS=""
      ;;
    feature)
      # plan-design-system is conditional (backend-only features skip; frontend features run).
      # quality-uiux is conditional (frontend features only); deliver-deploy/onboarding conditional (non-internal features).
      EXPECTED_SKILLS="discover-codebase-analysis concept-slides build-wireframe plan-design-system build-prototype iterate-prototype harden build-pr-workflow build-tdd quality-code-review quality-test-plan quality-test-execution quality-uiux deliver-deploy deliver-onboarding support-gotcha"
      EXPECTED_AGENTS=""
      ;;
    bugfix)
      EXPECTED_SKILLS="support-debug build-tdd quality-code-review build-pr-workflow support-gotcha"
      EXPECTED_AGENTS=""
      ;;
    hotfix)
      EXPECTED_SKILLS="support-debug build-tdd quality-test-execution quality-code-review deliver-deploy support-gotcha"
      EXPECTED_AGENTS=""
      ;;
    refactor)
      EXPECTED_SKILLS="discover-codebase-analysis plan-brainstorm plan-task-decompose build-tdd quality-code-review quality-test-execution build-pr-workflow support-gotcha"
      EXPECTED_AGENTS=""
      ;;
    dream)
      # support-wiki-bootstrap is conditional (only if aiwiki/ is missing at Step 2).
      EXPECTED_SKILLS="support-dream"
      EXPECTED_AGENTS=""
      ;;
    forge-evolve)
      # Steps 5 + 7 require support-skill-validator before and after applying changes.
      EXPECTED_SKILLS="support-skill-validator"
      EXPECTED_AGENTS=""
      ;;
    parallel)
      # support-parallel is the dispatcher; per-task inner skills depend on the user-supplied task list.
      EXPECTED_SKILLS="support-parallel"
      EXPECTED_AGENTS=""
      ;;
    setup)
      # Step 4 requires support-wiki-bootstrap to scaffold aiwiki/.
      # graphify is conditional (only if Step 1 user accepts the CLI / graph install offer),
      # and it's a Claude-Code-level skill rather than a forge skill — kept out of the required set.
      EXPECTED_SKILLS="support-wiki-bootstrap"
      EXPECTED_AGENTS=""
      ;;
    validate)
      # Step 1 requires support-skill-validator in full-scan mode.
      EXPECTED_SKILLS="support-skill-validator"
      EXPECTED_AGENTS=""
      ;;
    discover|note|resume|status|wrap)
      # Meta commands: read-only orientation, pure file-append, or delegation to an owning command.
      # No skill dispatch expected — telemetry records from concurrent work in the same session
      # surface in the top-level "Skills Called" section above, not as a compliance failure here.
      # (/discover Section 5 mentions support-system-guide as a drill-down for users, not a step-level dispatch.)
      EXPECTED_SKILLS=""
      EXPECTED_AGENTS=""
      ;;
    *)
      echo "Unknown command: $COMMAND"
      exit 1
      ;;
  esac

  ACTUAL_SKILLS=$(jq -r 'select(.type == "skill") | .name' "$TELEMETRY_FILE" | sort -u)
  ACTUAL_AGENTS=$(jq -r 'select(.type == "agent") | .name' "$TELEMETRY_FILE" | sort -u)

  echo "### Skills"
  if [ -n "$EXPECTED_SKILLS" ]; then
    for skill in $EXPECTED_SKILLS; do
      if echo "$ACTUAL_SKILLS" | grep -q "^${skill}$"; then
        echo "  ✓ $skill"
      else
        echo "  ✗ $skill — MISSING"
      fi
    done
  else
    echo "  (none expected for /$COMMAND)"
  fi

  echo ""
  echo "### Agents"
  if [ -n "$EXPECTED_AGENTS" ]; then
    for agent in $EXPECTED_AGENTS; do
      if echo "$ACTUAL_AGENTS" | grep -q "^${agent}$"; then
        echo "  ✓ $agent"
      else
        echo "  ✗ $agent — MISSING"
      fi
    done
  else
    echo "  (none expected for /$COMMAND)"
  fi

  echo ""

  # Unexpected calls — only meaningful when the command declares an expected set.
  # Skip for meta commands with no expected skills; otherwise every concurrent skill in
  # the same telemetry file would be flagged.
  if [ -n "$EXPECTED_SKILLS" ]; then
    UNEXPECTED=""
    for skill in $ACTUAL_SKILLS; do
      if ! echo "$EXPECTED_SKILLS" | tr ' ' '\n' | grep -q "^${skill}$"; then
        UNEXPECTED="$UNEXPECTED $skill"
      fi
    done
    if [ -n "$UNEXPECTED" ]; then
      echo "### Unexpected skills called:$UNEXPECTED"
    fi
  fi
fi
