// tools/generate-tests/generators/advanced-testing-generator.ts — SPEC-049
// Generates advanced testing scaffolds: property-based, mutation config, a11y, chaos runbook.
import { detectPropertyBasedNeed, generatePropertyScaffold, generateMutationConfig, getMutationTool, generateChaosRunbook, buildChaosRunbookMarkdown, isKubernetesProject, generateA11yTests, isWebProject, } from '../../../engine/advanced-testing/index.js';
/** Criteria keywords that trigger property-based test generation. */
const CRITICAL_KEYWORDS = ['critical', 'payment', 'auth', 'security', 'financial', 'core'];
/** Return true if the spec involves a critical module needing mutation config. */
function isCriticalModule(spec) {
    const text = `${spec.title} ${spec.tags.join(' ')}`.toLowerCase();
    return CRITICAL_KEYWORDS.some((kw) => text.includes(kw));
}
/** Join all spec criteria text for keyword detection. */
function getCriteriaText(spec) {
    // Use title and tags as a proxy for criteria text
    return `${spec.title} ${spec.tags.join(' ')}`;
}
/**
 * Return true when the project has advanced testing patterns to generate.
 * Detects property-based needs, critical modules, k8s, or web projects.
 */
export function isAdvancedTestingProject(spec, knowledge) {
    const criteriaText = getCriteriaText(spec);
    if (detectPropertyBasedNeed(criteriaText)) {
        return true;
    }
    if (isCriticalModule(spec)) {
        return true;
    }
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data may omit required fields
    const toolingKeys = Object.keys(knowledge.tooling ?? {});
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data may omit required fields
    const stackEntries = knowledge.stack ?? [];
    if (isKubernetesProject([...toolingKeys, ...stackEntries])) {
        return true;
    }
    if (isWebProject(stackEntries)) {
        return true;
    }
    return false;
}
/**
 * Generate advanced testing test definitions (used for the test plan summary).
 */
export function generateAdvancedTestingDefs(spec, testDir) {
    const defs = [];
    defs.push({
        name: `${spec.title} — Property-Based: invariant properties hold for all valid inputs`,
        type: 'unit',
        file: `${testDir}/advanced/`,
        description: 'Verify invariant properties using property-based testing (fast-check/Hypothesis)',
        priority: 'high',
        automatable: true,
    });
    if (isCriticalModule(spec)) {
        defs.push({
            name: `${spec.title} — Mutation: mutation score ≥ 80%`,
            type: 'unit',
            file: `${testDir}/advanced/`,
            description: 'Run mutation testing (Stryker/mutmut) and verify mutation score ≥ 80%',
            priority: 'high',
            automatable: true,
        });
    }
    return defs;
}
/** Generate a property-based test file for the spec. */
function buildPropertyBasedTestFile(spec, testDir, language, autoGenerate) {
    const criteriaText = getCriteriaText(spec);
    const invariantHint = detectPropertyBasedNeed(criteriaText)
        ? 'invariant: output is within expected range for any valid input'
        : 'idempotent: applying N times equals applying 1 time';
    const scaffold = generatePropertyScaffold(language, invariantHint);
    const ext = language === 'python' ? 'py' : 'ts';
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    return {
        path: `${testDir}/advanced/${slug}.property.${ext}`,
        framework: language === 'python' ? 'hypothesis' : 'fast-check',
        content: scaffold.scaffold,
        ready: autoGenerate,
    };
}
/** Generate a mutation testing config file for the spec. */
function buildMutationConfigFile(spec, testDir, language, autoGenerate) {
    const tool = getMutationTool(language);
    const mutationConfig = generateMutationConfig(tool, language);
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    const ext = language === 'python' ? 'cfg' : 'mjs';
    return {
        path: `${testDir}/advanced/${slug}.mutation.${ext}`,
        framework: tool,
        content: mutationConfig.configFile,
        ready: autoGenerate,
    };
}
/** Generate a chaos runbook file for the spec. */
function buildChaosRunbookFile(spec, testDir, autoGenerate) {
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    const experiments = generateChaosRunbook('staging');
    const content = buildChaosRunbookMarkdown('staging', experiments);
    return {
        path: `${testDir}/advanced/${slug}.chaos.md`,
        framework: 'litmuschaos',
        content,
        ready: autoGenerate,
    };
}
/** Generate an accessibility test file for the spec. */
function buildA11yTestFile(spec, testDir, language, autoGenerate) {
    const testFramework = language === 'typescript' || language === 'javascript' ? 'playwright' : 'pa11y';
    const a11yScaffold = generateA11yTests(testFramework);
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    const ext = language === 'typescript' ? 'ts' : 'js';
    return {
        path: `${testDir}/advanced/${slug}.a11y.${ext}`,
        framework: a11yScaffold.framework,
        content: a11yScaffold.testFile,
        ready: autoGenerate,
    };
}
/**
 * Generate advanced testing test files for the spec.
 * Generates property-based scaffolds, mutation configs, a11y tests, and chaos runbooks.
 */
export function generateAdvancedTestingFiles(spec, testDir, language, knowledge, autoGenerate) {
    const files = [];
    const criteriaText = getCriteriaText(spec);
    // Property-based test scaffold
    if (detectPropertyBasedNeed(criteriaText) || isCriticalModule(spec)) {
        files.push(buildPropertyBasedTestFile(spec, testDir, language, autoGenerate));
    }
    // Mutation config for critical modules
    if (isCriticalModule(spec)) {
        files.push(buildMutationConfigFile(spec, testDir, language, autoGenerate));
    }
    // Chaos runbook for k8s projects
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data may omit required fields
    const projectFiles = Object.keys(knowledge.tooling ?? {}).concat(knowledge.stack ?? []);
    if (isKubernetesProject(projectFiles)) {
        files.push(buildChaosRunbookFile(spec, testDir, autoGenerate));
    }
    // A11y tests for web projects
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime data may omit required fields
    if (isWebProject(knowledge.stack ?? [])) {
        files.push(buildA11yTestFile(spec, testDir, language, autoGenerate));
    }
    return files;
}
//# sourceMappingURL=advanced-testing-generator.js.map