// engine/advanced-testing/property-based.ts — SPEC-049
// Detects property-based testing needs and generates scaffold code.
/** Keywords (case-insensitive) that indicate a property-based testing need. */
const PBT_KEYWORDS_ES = [
    'siempre',
    'nunca',
    'para cualquier',
    'para todos',
    'invariant',
    'idempotent',
    'commutative',
    'conmutativo',
    'idempotente',
];
const PBT_KEYWORDS_EN = [
    'always',
    'never',
    'for any',
    'for all',
    'invariant',
    'idempotent',
    'commutative',
];
/** All keywords that trigger PBT detection. */
const PBT_KEYWORDS = [...PBT_KEYWORDS_ES, ...PBT_KEYWORDS_EN];
/**
 * Detect if the given criteria text suggests property-based testing is needed.
 * Uses a conservative approach: requires strong invariant keywords.
 */
export function detectPropertyBasedNeed(criteria) {
    const lower = criteria.toLowerCase();
    return PBT_KEYWORDS.some((kw) => lower.includes(kw));
}
/** Map a language identifier to its property test framework. */
export function getPropertyTestFramework(language) {
    const lang = language.toLowerCase();
    if (lang === 'typescript' || lang === 'javascript') {
        return 'fast-check';
    }
    if (lang === 'python') {
        return 'hypothesis';
    }
    if (lang === 'rust') {
        return 'proptest';
    }
    if (lang === 'java' || lang === 'kotlin') {
        return 'jqwik';
    }
    if (lang === 'go') {
        return 'gopter';
    }
    if (lang === 'haskell') {
        return 'quickcheck';
    }
    if (lang === 'scala') {
        return 'scalacheck';
    }
    return 'fast-check';
}
/** Generate the scaffold code for a fast-check (JS/TS) property test. */
function buildFastCheckScaffold(invariantHint) {
    return `import * as fc from 'fast-check';
import { describe, it, expect } from 'vitest';

describe('Property-based tests — ${invariantHint}', () => {
  it('${invariantHint}', () => {
    fc.assert(
      fc.property(fc.integer(), fc.integer(), (a, b) => {
        // TODO: replace with the actual function under test
        const result = yourFunction(a, b);
        // Assert the invariant holds for any valid input
        expect(result).toBeDefined();
      }),
    );
  });
});
`;
}
/** Generate the scaffold code for a Hypothesis (Python) property test. */
function buildHypothesisScaffold(invariantHint) {
    return `from hypothesis import given, settings, HealthCheck
from hypothesis import strategies as st


@given(st.integers(), st.integers())
@settings(
    max_examples=100,
    suppress_health_check=[HealthCheck.too_slow],
    deadline=None,
)
def test_${invariantHint.toLowerCase().replace(/[^a-z0-9]/g, '_')}(a: int, b: int) -> None:
    """${invariantHint}"""
    # TODO: replace with the actual function under test
    result = your_function(a, b)
    # Assert the invariant holds for any valid input
    assert result is not None
`;
}
/** Generate the scaffold code for a proptest (Rust) property test. */
function buildProptestScaffold(invariantHint) {
    return `use proptest::prelude::*;

proptest! {
    #[test]
    fn test_${invariantHint.toLowerCase().replace(/[^a-z0-9]/g, '_')}(a in any::<i32>(), b in any::<i32>()) {
        // ${invariantHint}
        // TODO: replace with the actual function under test
        let result = your_function(a, b);
        // Assert the invariant holds for any valid input
        prop_assert!(result.is_ok());
    }
}
`;
}
/** Generate the scaffold code for a jqwik (Java) property test. */
function buildJqwikScaffold(invariantHint) {
    return `import net.jqwik.api.*;

class ${invariantHint.replace(/[^a-zA-Z0-9]/g, '')}PropertyTest {

    @Property
    boolean ${invariantHint.toLowerCase().replace(/[^a-z0-9]/g, '_')}(
            @ForAll int a,
            @ForAll int b) {
        // TODO: replace with the actual method under test
        Object result = yourMethod(a, b);
        // Assert the invariant holds for any valid input
        return result != null;
    }
}
`;
}
/** Generate the scaffold code for a gopter (Go) property test. */
function buildGopterScaffold(invariantHint) {
    return `package mypackage_test

import (
    "testing"

    "github.com/leanovate/gopter"
    "github.com/leanovate/gopter/gen"
    "github.com/leanovate/gopter/prop"
)

func Test${invariantHint.replace(/[^a-zA-Z0-9]/g, '')}(t *testing.T) {
    properties := gopter.NewProperties(nil)
    properties.Property("${invariantHint}", prop.ForAll(
        func(a, b int) bool {
            // TODO: replace with the actual function under test
            result := YourFunction(a, b)
            // Assert the invariant holds for any valid input
            return result != nil
        },
        gen.Int(), gen.Int(),
    ))
    properties.TestingRun(t)
}
`;
}
/**
 * Generate a property-based testing scaffold for the given language and invariant description.
 * Returns a PropertyScaffold with the framework name, invariant description, and scaffold code.
 */
export function generatePropertyScaffold(language, invariantHint) {
    const framework = getPropertyTestFramework(language);
    let scaffold = buildFastCheckScaffold(invariantHint);
    switch (framework) {
        case 'hypothesis':
            scaffold = buildHypothesisScaffold(invariantHint);
            break;
        case 'proptest':
            scaffold = buildProptestScaffold(invariantHint);
            break;
        case 'jqwik':
            scaffold = buildJqwikScaffold(invariantHint);
            break;
        case 'gopter':
            scaffold = buildGopterScaffold(invariantHint);
            break;
        case 'fast-check':
        case 'quickcheck':
        case 'scalacheck':
            scaffold = buildFastCheckScaffold(invariantHint);
            break;
    }
    return {
        name: `Property test — ${invariantHint}`,
        invariant: invariantHint,
        scaffold,
    };
}
//# sourceMappingURL=property-based.js.map