// engine/test-generators/mock-generator.ts
// SPEC-018: Mock generation for API endpoints (realistic data, delays, error responses)
// === Realistic sample data generators ===
function generateSampleId() {
    return '550e8400-e29b-41d4-a716-446655440000';
}
function generateSampleData(resource) {
    return {
        id: generateSampleId(),
        name: `Sample ${resource}`,
        description: `Auto-generated sample for ${resource} (Planu SPEC-018)`,
        status: 'active',
        createdAt: '2025-01-15T10:30:00.000Z',
        updatedAt: '2025-01-15T10:30:00.000Z',
        email: `user@example.com`,
        count: 42,
        tags: ['sample', 'generated'],
        metadata: { source: 'planu', version: '1.0' },
    };
}
const ERROR_RESPONSES = [
    {
        status: 400,
        body: { error: 'Bad Request', message: 'Validation failed', code: 'VALIDATION_ERROR' },
    },
    {
        status: 401,
        body: { error: 'Unauthorized', message: 'Authentication required', code: 'AUTH_REQUIRED' },
    },
    {
        status: 403,
        body: { error: 'Forbidden', message: 'Insufficient permissions', code: 'FORBIDDEN' },
    },
    { status: 404, body: { error: 'Not Found', message: 'Resource not found', code: 'NOT_FOUND' } },
    {
        status: 422,
        body: {
            error: 'Unprocessable Entity',
            message: 'Business rule violation',
            code: 'UNPROCESSABLE',
        },
    },
    {
        status: 500,
        body: {
            error: 'Internal Server Error',
            message: 'Unexpected server error',
            code: 'INTERNAL_ERROR',
        },
    },
];
function getErrorResponsesForEndpoint(statusCodes) {
    return ERROR_RESPONSES.filter((er) => statusCodes.includes(er.status));
}
// === Mock definition builders ===
/**
 * Build an ApiMockDefinition from a ContractSpecEndpoint.
 */
function buildMockFromEndpoint(endpoint, resource) {
    const sampleData = endpoint.method === 'GET' && endpoint.path.endsWith('}')
        ? generateSampleData(resource)
        : endpoint.method === 'GET'
            ? { items: [generateSampleData(resource)], total: 1, page: 1, pageSize: 20 }
            : generateSampleData(resource);
    return {
        endpoint: endpoint.path,
        method: endpoint.method,
        sampleData,
        delayMs: 250,
        errorResponses: getErrorResponsesForEndpoint(endpoint.statusCodes),
    };
}
/**
 * Generate mock definitions from a list of endpoints.
 */
export function generateMockDefinitions(endpoints, specTitle) {
    const resource = specTitle
        .toLowerCase()
        .replace(/[^a-z0-9]/g, '-')
        .replace(/-+/g, '-');
    return endpoints.map((ep) => buildMockFromEndpoint(ep, resource));
}
// === MSW (Mock Service Worker) content generation ===
function buildMswMockContent(mocks, specTitle) {
    const handlerLines = [];
    for (const mock of mocks) {
        const method = mock.method.toLowerCase();
        const handlerName = `${method}${mock.endpoint.replace(/[^a-zA-Z0-9]/g, '').replace(/id$/i, 'ById')}`;
        handlerLines.push(`  http.${method}('${mock.endpoint}', async () => {`, `    // Simulate network delay: ${mock.delayMs}ms`, `    await delay(${mock.delayMs});`, `    return HttpResponse.json(${JSON.stringify(mock.sampleData, null, 6).replace(/\n/g, '\n    ')});`, `  }), // ${handlerName}`, '');
    }
    return `// MSW (Mock Service Worker) handlers — ${specTitle}
// Auto-generated by Planu SPEC-018
// Install: msw@2.x

import { http, HttpResponse, delay } from 'msw';

export const ${specTitle.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()}Handlers = [
${handlerLines.join('\n')}];

// Error scenario handlers (uncomment to simulate errors)
export const ${specTitle.replace(/[^a-zA-Z0-9]/g, '').toLowerCase()}ErrorHandlers = [
${mocks
        .flatMap((mock) => mock.errorResponses
        .slice(0, 2)
        .map((er) => `  // http.${mock.method.toLowerCase()}('${mock.endpoint}', () => HttpResponse.json(${JSON.stringify(er.body)}, { status: ${er.status} })),`))
        .join('\n')}
];
`;
}
// === json-server content generation ===
function buildJsonServerContent(mocks, specTitle) {
    const db = {};
    const resource = specTitle
        .toLowerCase()
        .replace(/[^a-z0-9]/g, '_')
        .replace(/_+/g, '_');
    // Build sample db structure for json-server
    for (const mock of mocks) {
        if (mock.method === 'GET') {
            const key = mock.endpoint.includes('{id}') ? null : resource;
            if (key !== null) {
                db[key] = [mock.sampleData];
            }
        }
    }
    return `// json-server database — ${specTitle}
// Auto-generated by Planu SPEC-018
// Install: json-server
// Run: npx json-server --watch db.json --port 3001

${JSON.stringify(db, null, 2)}
`;
}
// === WireMock content generation ===
function buildWiremockContent(mocks, _specTitle) {
    const stubs = mocks.map((mock) => ({
        request: {
            method: mock.method,
            url: mock.endpoint.replace(/{[^}]+}/g, '/[^/]+'),
            urlPattern: mock.endpoint.includes('{')
                ? mock.endpoint.replace(/{[^}]+}/g, '[^/]+')
                : undefined,
        },
        response: {
            status: mock.method === 'POST' ? 201 : 200,
            headers: { 'Content-Type': 'application/json' },
            jsonBody: mock.sampleData,
            fixedDelayMilliseconds: mock.delayMs,
        },
    }));
    return `// WireMock stubs — ${mocks[0]?.endpoint ?? 'API'}
// Auto-generated by Planu SPEC-018
// Place in: src/test/resources/__files/ (Java) or wiremock/mappings/ (standalone)

${stubs.map((stub) => JSON.stringify(stub, null, 2)).join('\n\n')}
`;
}
// === Main export ===
/**
 * Generate mock server content for the given tool.
 */
export function generateMockServerContent(mocks, specTitle, tool) {
    switch (tool) {
        case 'json-server':
            return buildJsonServerContent(mocks, specTitle);
        case 'wiremock':
            return buildWiremockContent(mocks, specTitle);
        case 'msw':
            return buildMswMockContent(mocks, specTitle);
        /* v8 ignore next 2 */
        default:
            return buildMswMockContent(mocks, specTitle);
    }
}
/**
 * Detect the best mock tool for the project stack.
 */
export function detectMockTool(stack) {
    const lower = stack.map((s) => s.toLowerCase());
    if (lower.some((s) => s.includes('msw'))) {
        return 'msw';
    }
    if (lower.some((s) => s.includes('json-server'))) {
        return 'json-server';
    }
    if (lower.some((s) => s.includes('wiremock') || s.includes('spring'))) {
        return 'wiremock';
    }
    // Default: MSW (best for JS/TS frontends)
    return 'msw';
}
/**
 * Get the file extension for a mock tool output.
 */
export function getMockFileExtension(tool) {
    const extMap = {
        msw: 'ts',
        'json-server': 'json',
        wiremock: 'json',
    };
    return extMap[tool];
}
//# sourceMappingURL=mock-generator.js.map