// engine/generate-tests/generators/property-based-generator.ts — SPEC-315
// High-level generator: produces a full test file string from spec + context.
import { extractPropertyTests, detectPropertyFramework } from '../../property-test-generator.js';
// ---------------------------------------------------------------------------
// File header builders per framework
// ---------------------------------------------------------------------------
function buildFastCheckHeader(specTitle) {
    return `// Property-based tests for: ${specTitle}
// Generated by Planu SDD — strategy:property-based (SPEC-315)
// Framework: fast-check

import * as fc from 'fast-check';
import { describe, it } from 'vitest';

describe('${specTitle} — property-based tests', () => {`;
}
function buildHypothesisHeader(specTitle) {
    return `# Property-based tests for: ${specTitle}
# Generated by Planu SDD — strategy:property-based (SPEC-315)
# Framework: hypothesis

from hypothesis import given, settings, HealthCheck
from hypothesis import strategies as st


class Test${specTitle.replace(/[^a-zA-Z0-9]/g, '')}Properties:
    """Property-based tests for ${specTitle}."""
`;
}
function buildJqwikHeader(specTitle) {
    const className = specTitle.replace(/[^a-zA-Z0-9]/g, '');
    return `// Property-based tests for: ${specTitle}
// Generated by Planu SDD — strategy:property-based (SPEC-315)
// Framework: jqwik

import net.jqwik.api.*;
import static org.assertj.core.api.Assertions.assertThat;

class ${className}PropertyTest {`;
}
function buildGenericHeader(specTitle) {
    return `# Property-based tests for: ${specTitle}
# Generated by Planu SDD — strategy:property-based (SPEC-315)
# Framework: generic (adapt to your property testing library)
#
# Each property below describes an invariant that must hold for ALL valid inputs.
# Implement using your project's property testing framework.
`;
}
// ---------------------------------------------------------------------------
// Test block builders per framework
// ---------------------------------------------------------------------------
function buildFastCheckBlock(test, index) {
    return `
  it('property ${index + 1}: ${test.invariant}', () => {
    // Input domain: ${test.inputDomain}
    // Shrink: ${test.shrinkStrategy}
    ${test.generatorCode}
  });`;
}
function buildHypothesisBlock(test, _index) {
    return `
    ${test.generatorCode}
`;
}
function buildJqwikBlock(test, _index) {
    return `
    // Input domain: ${test.inputDomain}
    // Shrink: ${test.shrinkStrategy}
    ${test.generatorCode}
`;
}
function buildGenericBlock(test, index) {
    return `
# Property ${index + 1}
${test.generatorCode}
`;
}
// ---------------------------------------------------------------------------
// File footer builders
// ---------------------------------------------------------------------------
function buildFastCheckFooter() {
    return '\n});\n';
}
function buildJqwikFooter() {
    return '\n}\n';
}
function buildNoFooter() {
    return '\n';
}
// ---------------------------------------------------------------------------
// No-properties fallback
// ---------------------------------------------------------------------------
function buildFallbackContent(specTitle, language) {
    if (language === 'python') {
        return `# Property-based tests for: ${specTitle}
# Generated by Planu SDD — strategy:property-based (SPEC-315)
# No invariants detected in acceptance criteria.
# Add criteria with keywords: "must be positive", "idempotent", "for any input", etc.
`;
    }
    return `// Property-based tests for: ${specTitle}
// Generated by Planu SDD — strategy:property-based (SPEC-315)
// No invariants detected in acceptance criteria.
// Add criteria with keywords: "must be positive", "idempotent", "for any input", etc.
`;
}
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Generate a complete property-based test file as a string.
 * Adapts output to fast-check (JS/TS), hypothesis (Python), jqwik (Java/Kotlin),
 * or pseudo-code generic format based on detected framework.
 *
 * @param spec - The spec metadata (title, id used for file naming/headers).
 * @param context - Project knowledge (language, stack) for framework detection.
 * @param criteria - Acceptance criteria strings extracted from spec.md by the caller.
 */
export function generatePropertyBasedTests(spec, context, criteria = []) {
    const framework = detectPropertyFramework(context.language, context.stack);
    const tests = extractPropertyTests({
        criteria,
        language: context.language,
        stack: context.stack,
    });
    if (tests.length === 0) {
        return buildFallbackContent(spec.title, context.language);
    }
    // Build header
    let header;
    let blockBuilder;
    let footer;
    switch (framework) {
        case 'fast-check':
            header = buildFastCheckHeader(spec.title);
            blockBuilder = buildFastCheckBlock;
            footer = buildFastCheckFooter();
            break;
        case 'hypothesis':
            header = buildHypothesisHeader(spec.title);
            blockBuilder = buildHypothesisBlock;
            footer = buildNoFooter();
            break;
        case 'jqwik':
            header = buildJqwikHeader(spec.title);
            blockBuilder = buildJqwikBlock;
            footer = buildJqwikFooter();
            break;
        case 'generic':
            header = buildGenericHeader(spec.title);
            blockBuilder = buildGenericBlock;
            footer = buildNoFooter();
            break;
    }
    const blocks = tests.map((test, i) => blockBuilder(test, i)).join('');
    return `${header}${blocks}${footer}`;
}
//# sourceMappingURL=property-based-generator.js.map