/**
 * Contract tests for the `## AGENT MEMORY` catalog injection and
 * post-compaction nudge inside agentScheduler. We source-grep — the
 * contracts are:
 *   - The catalog injection block exists, is gated on the `memory`
 *     capability, calls memoryService.getCatalog, lists `id  title`
 *     compactly, and is wrapped in try/catch.
 *   - The post-compaction nudge is a one-shot flag-driven block
 *     keyed off `_postCompactionNudgePending`, and the flag is set
 *     after the compaction step succeeds.
 */
import { describe, test, expect } from '@jest/globals';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __dirname = dirname(fileURLToPath(import.meta.url));
const SRC = readFileSync(join(__dirname, '../agentScheduler.js'), 'utf-8');

describe('agentScheduler — AGENT MEMORY catalog injection', () => {
  test('source contains the AGENT MEMORY catalog injection header', () => {
    expect(SRC).toMatch(/AGENT MEMORY \(catalog/);
  });

  test('injection sources from memoryService.getCatalog', () => {
    expect(SRC).toMatch(/getMemoryService/);
    expect(SRC).toMatch(/getCatalog\(agentId/);
  });

  test('injection is gated on the `memory` capability', () => {
    const start = SRC.indexOf('Auto-inject AGENT MEMORY');
    const block = SRC.slice(start, start + 1500);
    expect(block).toMatch(/capabilities\.includes\(['"]memory['"]\)/);
  });

  test('injection follows the CODEBASE KNOWLEDGE block (stable ordering for prompt cache)', () => {
    const cbIdx = SRC.indexOf('Auto-inject CODEBASE KNOWLEDGE');
    const memIdx = SRC.indexOf('Auto-inject AGENT MEMORY');
    expect(cbIdx).toBeGreaterThan(-1);
    expect(memIdx).toBeGreaterThan(-1);
    expect(memIdx).toBeGreaterThan(cbIdx);
  });

  test('graceful degrade: wrapped in try/catch', () => {
    const start = SRC.indexOf('AGENT MEMORY');
    const block = SRC.slice(Math.max(0, start - 600), start + 800);
    expect(block).toMatch(/try\s*\{/);
    expect(block).toMatch(/catch\s*\(/);
  });
});

describe('agentScheduler — POST-COMPACTION NUDGE', () => {
  test('source contains the POST-COMPACTION NUDGE block', () => {
    expect(SRC).toMatch(/POST-COMPACTION NUDGE/);
  });

  test('nudge is driven by the _postCompactionNudgePending flag (one-shot)', () => {
    expect(SRC).toMatch(/_postCompactionNudgePending/);
    const block = SRC.slice(
      SRC.indexOf('POST-COMPACTION NUDGE') - 200,
      SRC.indexOf('POST-COMPACTION NUDGE') + 600,
    );
    // The flag is consumed (set false) after emission.
    expect(block).toMatch(/_postCompactionNudgePending\s*=\s*false/);
  });

  test('the flag is set after the compaction step', () => {
    // Look for a place that flips the flag to true (not false).
    expect(SRC).toMatch(/_postCompactionNudgePending\s*=\s*true/);
  });

  test('nudge references AGENT MEMORY so the agent knows where to look', () => {
    const start = SRC.indexOf('POST-COMPACTION NUDGE');
    const block = SRC.slice(start, start + 1200);
    expect(block).toMatch(/AGENT MEMORY/);
    expect(block).toMatch(/memory read/);
  });
});
