import { describe, expect, it } from 'vitest';
import fs from 'node:fs/promises';
import path from 'node:path';

/**
 * Regression guard for issue: "Cannot open file ... lbug.shadow - Error 2"
 *
 * Read-only HTTP endpoints (graph, search, grep) must open the LadybugDB with
 * `{ readOnly: true }` so the engine never engages the checkpoint machinery
 * (`.shadow` sidecar). Write-mode opens for read-only operations were the
 * trigger for the Windows-only "Cannot open file ... lbug.shadow" failures
 * observed in E2E runs.
 *
 * If you add another read-only endpoint and forget the option, this file
 * fails — keeping the contract explicit at the static-analysis layer.
 *
 * Companion: api-query-readonly-wiring.test.ts (covers /api/query).
 * Precedent: PR #1655 set the pattern for /api/query.
 */
describe('api read-only endpoint wiring', () => {
  const readSource = () =>
    fs.readFile(path.join(__dirname, '..', '..', 'src', 'server', 'api.ts'), 'utf-8');

  it('/api/graph stream path opens read-only', async () => {
    const source = await readSource();
    expect(source).toMatch(
      /streamGraphNdjson\(res, includeContent, abortController\.signal\)[\s\S]{0,200}readOnly:\s*true/,
    );
  });

  it('/api/graph non-stream path opens read-only', async () => {
    const source = await readSource();
    expect(source).toMatch(/buildGraph\(includeContent\)[\s\S]{0,80}readOnly:\s*true/);
  });

  it('/api/search opens read-only', async () => {
    const source = await readSource();
    // The /api/search handler ends its withLbugDb callback with
    // `return { searchResults: enriched, ftsAvailable };` immediately before
    // the closing brace + options object. Match that suffix to confirm the
    // search call site, not /api/query.
    expect(source).toMatch(/searchResults: enriched, ftsAvailable[\s\S]{0,80}readOnly:\s*true/);
  });

  it('/api/grep opens read-only', async () => {
    const source = await readSource();
    expect(source).toMatch(/MATCH \(n:File\)[\s\S]{0,300}readOnly:\s*true/);
  });

  it('/api/embed remains write-mode (writes embeddings — must not be flipped to readOnly)', async () => {
    const source = await readSource();
    // Negative assertion: no `readOnly: true` between the embed job's
    // `runEmbeddingPipeline` call site and its withLbugDb open. Embed writes
    // back vector rows; flipping this to readOnly would silently break it.
    const embedSection = source.match(/runEmbeddingPipeline[\s\S]{0,400}\}\s*\)\s*;[\s\S]{0,200}/);
    if (embedSection) {
      expect(embedSection[0]).not.toMatch(/readOnly:\s*true/);
    }
  });
});
