/**
 * Contract tests for the `## CODEBASE KNOWLEDGE` injection in
 * agentScheduler. Like the sibling tests for task-list and operating-
 * posture, we source-grep rather than instantiating the heavy
 * scheduler graph — the contract is: the injection block exists, sits
 * in the right place, sources from the singleton service, and is
 * wrapped in a graceful-degrade try/catch.
 */
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 — CODEBASE KNOWLEDGE injection', () => {
  test('source contains the injection block', () => {
    expect(SRC).toMatch(/Auto-inject CODEBASE KNOWLEDGE/);
  });

  test('injection sources from codebaseKnowledgeService singleton', () => {
    expect(SRC).toMatch(/codebaseKnowledgeService/);
    expect(SRC).toMatch(/getCodebaseKnowledgeService/);
    expect(SRC).toMatch(/buildIndexBlock\(agentId\)/);
  });

  test('injection follows the CURRENT TASK LIST block (stable ordering for prompt cache)', () => {
    const taskIdx = SRC.indexOf('CURRENT TASK LIST');
    const cbIdx = SRC.indexOf('CODEBASE KNOWLEDGE');
    expect(taskIdx).toBeGreaterThan(-1);
    expect(cbIdx).toBeGreaterThan(-1);
    expect(cbIdx).toBeGreaterThan(taskIdx);
  });

  test('graceful degrade: wrapped in try/catch with a `continuing without` warning', () => {
    const block = SRC.slice(
      SRC.indexOf('Auto-inject CODEBASE KNOWLEDGE'),
      SRC.indexOf('Check if streaming is enabled'),
    );
    expect(block).toMatch(/try\s*\{/);
    expect(block).toMatch(/catch\s*\(/);
    expect(block).toMatch(/continuing without/);
  });

  test('REGRESSION: injection is GATED on the agent having code-map in capabilities', () => {
    // Non-coder agents (chat-only, marketing agents, etc.) must not
    // pay the per-turn service-lookup cost. The cache is only
    // populated by code-map results — agents without code-map have
    // nothing to surface.
    const block = SRC.slice(
      SRC.indexOf('Auto-inject CODEBASE KNOWLEDGE'),
      SRC.indexOf('Check if streaming is enabled'),
    );
    // Must check capabilities for 'code-map' before doing anything.
    expect(block).toMatch(/agent\.capabilities/);
    expect(block).toMatch(/includes\(['"]code-map['"]\)/);
    // The whole try-block should sit INSIDE that conditional, not
    // outside it (otherwise the gate doesn't actually skip the work).
    const guardIdx = block.indexOf('includes(\'code-map\')');
    const tryIdx   = block.indexOf('try {');
    expect(guardIdx).toBeGreaterThan(-1);
    expect(tryIdx).toBeGreaterThan(guardIdx);
  });
});
