// tools/generate-tests/generators/event-test-generator.ts — Event test scaffolds (SPEC-031)
// Generates DLQ and idempotence test definitions and file scaffolds.
import { detectBrokers, getBrokerConfig, requiresIdempotence, supportsDLQ, } from '../../../engine/event-detector.js';
/**
 * Returns true when the project uses a known event broker.
 */
export function isEventProject(knowledge) {
    const brokers = detectBrokers(knowledge.stack);
    return brokers.length > 0 && brokers[0] !== 'unknown';
}
/**
 * Generate test definitions for event-driven features:
 * - DLQ routing after N retries
 * - DLQ re-injection
 * - Idempotence (duplicate event produces same state)
 */
export function generateEventTestDefs(title, testDir, knowledge) {
    const defs = [];
    const brokers = detectBrokers(knowledge.stack);
    /* v8 ignore start */ // detectBrokers always returns a non-empty array; ?? fallback unreachable
    const primaryBroker = brokers[0] ?? 'unknown';
    /* v8 ignore stop */
    if (supportsDLQ(primaryBroker)) {
        defs.push({
            name: `${title} — DLQ: invalid payload routes to DLQ after max retries`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'Verify that an event with invalid payload is retried N times then sent to DLQ',
            priority: 'critical',
            automatable: true,
        });
        defs.push({
            name: `${title} — DLQ: re-injection from DLQ processes correctly`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'Verify that re-injecting a corrected event from DLQ is processed successfully',
            priority: 'high',
            automatable: true,
        });
    }
    if (requiresIdempotence(primaryBroker)) {
        defs.push({
            name: `${title} — Idempotence: duplicate event produces same final state`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'Send the same event twice and verify the system state equals one-time processing',
            priority: 'critical',
            automatable: true,
        });
    }
    return defs;
}
/**
 * Generate test file scaffolds for event-driven features.
 */
export function generateEventTestFiles(spec, testDir, testFramework, language, knowledge, autoGenerate) {
    const brokers = detectBrokers(knowledge.stack);
    /* v8 ignore start */ // detectBrokers always returns a non-empty array; ?? fallback unreachable
    const primaryBroker = brokers[0] ?? 'unknown';
    /* v8 ignore stop */
    const hasDLQ = supportsDLQ(primaryBroker);
    const needsIdempotence = requiresIdempotence(primaryBroker);
    if (!hasDLQ && !needsIdempotence) {
        return [];
    }
    const brokerConfig = getBrokerConfig(primaryBroker);
    // brokerConfig is always non-null here: if primaryBroker were 'unknown', both
    // supportsDLQ and requiresIdempotence return false and we returned early above.
    /* v8 ignore start */
    const brokerName = brokerConfig?.displayName ?? 'event broker';
    /* v8 ignore stop */
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    const ext = getTestExt(language);
    const files = [];
    // hasDLQ || needsIdempotence is always true here (we returned early when both false above).
    const content = language === 'python'
        ? generatePythonEventTest(spec.title, brokerName, hasDLQ, needsIdempotence)
        : generateJsEventTest(spec.title, brokerName, testFramework, hasDLQ, needsIdempotence);
    files.push({
        path: `${testDir}/integration/${slug}.event.test.${ext}`,
        framework: testFramework,
        content,
        ready: autoGenerate,
    });
    return files;
}
// ---------------------------------------------------------------------------
// Content generators
// ---------------------------------------------------------------------------
function generateJsEventTest(title, brokerName, framework, hasDLQ, needsIdempotence) {
    const isVitest = framework === 'vitest';
    const runner = isVitest ? 'vitest' : 'jest';
    const lines = [
        `// Event-driven tests for: ${title}`,
        `// Broker: ${brokerName}`,
        '// Generated by Planu SDD MCP Server (SPEC-031)',
        '',
        `import { describe, it, expect, beforeEach } from '${runner}'`,
        '',
        `describe('${title} — Event-Driven Tests', () => {`,
    ];
    if (hasDLQ) {
        lines.push('', `  describe('DLQ routing', () => {`, `    it('routes event with invalid payload to DLQ after max retries', async () => {`, `      // Arrange: create a consumer with retry policy (max 3 retries, DLQ enabled)`, `      // TODO: set up your consumer with DLQ configuration`, '', `      // Act: publish an event with a missing required field`, `      const invalidPayload = { /* missing required fields */ }`, `      // TODO: await publishEvent(invalidPayload)`, '', `      // Assert: after 3 retries, event appears in DLQ`, `      // TODO: const dlqMessages = await drainDLQ()`, `      // expect(dlqMessages).toHaveLength(1)`, `      // expect(dlqMessages[0].payload).toEqual(invalidPayload)`, `      expect(true).toBe(true) // Replace with real DLQ assertion`, `    })`, '', `    it('re-injects corrected event from DLQ and processes successfully', async () => {`, `      // Arrange: place a corrected event in the DLQ`, `      // TODO: await injectIntoDLQ(correctedPayload)`, '', `      // Act: trigger DLQ re-injection process`, `      // TODO: await reInjectFromDLQ()`, '', `      // Assert: event was processed correctly`, `      // TODO: const result = await getProcessedResult(correctedPayload.id)`, `      // expect(result.status).toBe('processed')`, `      expect(true).toBe(true) // Replace with real re-injection assertion`, `    })`, `  })`);
    }
    if (needsIdempotence) {
        lines.push('', `  describe('Idempotence', () => {`, `    it('processing the same event twice produces the same final state', async () => {`, `      // Arrange: create a valid event with a unique ID`, `      const eventId = 'test-event-id-001'`, `      const payload = { id: eventId, /* other fields */ }`, '', `      // Act: process the same event twice`, `      // TODO: await processEvent(payload)`, `      // TODO: await processEvent(payload) // second time — must be idempotent`, '', `      // Assert: system state is the same as after one processing`, `      // TODO: const state = await getSystemState(eventId)`, `      // expect(state.processedCount).toBe(1) // NOT 2`, `      expect(true).toBe(true) // Replace with real idempotence assertion`, `    })`, `  })`);
    }
    lines.push(`})`, '');
    return lines.join('\n');
}
function generatePythonEventTest(title, brokerName, hasDLQ, needsIdempotence) {
    const lines = [
        `# Event-driven tests for: ${title}`,
        `# Broker: ${brokerName}`,
        '# Generated by Planu SDD MCP Server (SPEC-031)',
        '',
        'import pytest',
        '',
        `class Test${title.replace(/\s+/g, '')}EventDriven:`,
    ];
    // hasDLQ=false with needsIdempotence=true is unreachable: no broker in current config
    // supports idempotence without DLQ. The else-branch of this if is therefore uncoverable.
    /* v8 ignore next 1 */
    if (hasDLQ) {
        lines.push('', `    def test_invalid_payload_routes_to_dlq(self):`, `        """Event with invalid payload goes to DLQ after max retries."""`, `        # TODO: publish invalid event and verify DLQ after retries`, `        pass`, '', `    def test_dlq_reinjection_processes_correctly(self):`, `        """Corrected event re-injected from DLQ is processed successfully."""`, `        # TODO: inject corrected event and verify processed state`, `        pass`);
    }
    if (needsIdempotence) {
        lines.push('', `    def test_duplicate_event_idempotent(self):`, `        """Processing the same event twice produces the same final state."""`, `        # TODO: process event twice and verify state == once-processed`, `        pass`);
    }
    return lines.join('\n');
}
function getTestExt(language) {
    const exts = {
        typescript: 'ts',
        javascript: 'js',
        python: 'py',
        go: 'go',
        rust: 'rs',
        java: 'java',
        kotlin: 'kt',
    };
    return exts[language] ?? 'ts';
}
//# sourceMappingURL=event-test-generator.js.map