// tools/challenge-spec-helpers.ts — Concurrency, risk, and spec-reader helpers for challenge-spec
import { readFile } from 'node:fs/promises';
// --- Concurrency analysis ---
export function generateConcurrencyAnalysis(_spec, content, _knowledge) {
    const lower = content.toLowerCase();
    const hotPaths = [];
    const raceConditions = [];
    const sharedState = [];
    const recommendations = [];
    // Detect hot paths
    if (lower.includes('login') || lower.includes('auth')) {
        hotPaths.push('Authentication endpoint (high-frequency, shared session state)');
    }
    if (lower.includes('list') || lower.includes('search') || lower.includes('feed')) {
        hotPaths.push('List/search endpoints (high read frequency)');
    }
    if (lower.includes('submit') || lower.includes('create') || lower.includes('update')) {
        hotPaths.push('Write endpoints (mutation-heavy, lock-prone)');
    }
    // Detect race conditions
    if (lower.includes('counter') ||
        lower.includes('increment') ||
        lower.includes('balance') ||
        lower.includes('stock') ||
        lower.includes('quantity') ||
        lower.includes('vote')) {
        raceConditions.push('Counter/balance updates may lose increments under concurrent writes');
        recommendations.push('Use database-level atomic increments (UPDATE SET count = count + 1) instead of read-modify-write');
    }
    if (lower.includes('status') && (lower.includes('update') || lower.includes('transition'))) {
        raceConditions.push('Status transitions may conflict when two users update simultaneously');
        recommendations.push('Use optimistic locking (version column) or pessimistic locking (SELECT FOR UPDATE)');
    }
    if (lower.includes('file') || lower.includes('upload') || lower.includes('resource')) {
        raceConditions.push('Concurrent file writes to same resource may corrupt data');
        recommendations.push('Use advisory locks or rename-and-swap pattern for file operations');
    }
    // Detect shared state
    if (lower.includes('session') || lower.includes('cart') || lower.includes('draft')) {
        sharedState.push('User session state (may be accessed from multiple tabs/devices)');
    }
    if (lower.includes('cache') || lower.includes('global') || lower.includes('config')) {
        sharedState.push('Global cache or configuration (requires synchronized access)');
    }
    // General recommendations
    if (raceConditions.length === 0) {
        recommendations.push('No obvious race conditions detected, but test concurrent scenarios in integration tests');
    }
    recommendations.push('Use database transactions for multi-step operations');
    recommendations.push('Implement idempotency keys for all mutation endpoints');
    return { hotPaths, raceConditions, sharedState, recommendations };
}
// --- Scalability and risk ---
export function buildScalabilityAssessment(spec, knowledge, scenarios) {
    const criticalCount = scenarios.filter((s) => s.impact === 'critical').length;
    const arch = knowledge.architecture.primary;
    const parts = [];
    parts.push(`Architecture: ${arch}. Spec scope: ${spec.scope}.`);
    if (criticalCount > 2) {
        parts.push(`WARNING: ${criticalCount} critical-impact scenarios identified. This spec requires careful scaling review.`);
    }
    else if (criticalCount > 0) {
        parts.push(`${criticalCount} critical scenario(s) require mitigation before deployment.`);
    }
    else {
        parts.push('No critical scalability concerns for the current scope.');
    }
    if (spec.scope === 'architectural' || spec.scope === 'cross-module') {
        parts.push('Cross-module scope increases blast radius. Consider phased rollout with feature flags.');
    }
    return parts.join(' ');
}
export function calculateOverallRisk(scenarios, concurrency) {
    const criticalCount = scenarios.filter((s) => s.impact === 'critical').length;
    const highCount = scenarios.filter((s) => s.impact === 'high').length;
    const raceCount = concurrency.raceConditions.length;
    if (criticalCount >= 3 || (criticalCount >= 2 && raceCount >= 2)) {
        return 'critical';
    }
    if (criticalCount >= 1 || highCount >= 3 || raceCount >= 3) {
        return 'high';
    }
    if (highCount >= 1 || raceCount >= 1) {
        return 'medium';
    }
    return 'low';
}
// --- Spec content reader ---
export async function readSpecContent(spec) {
    let content = `${spec.title} ${spec.type} ${spec.scope} ${spec.target} ${spec.tags.join(' ')}`;
    try {
        if (spec.specPath) {
            content += ' ' + (await readFile(spec.specPath, 'utf-8'));
        }
    }
    catch {
        /* file not available */
    }
    try {
        if (spec.technicalPath) {
            content += ' ' + (await readFile(spec.technicalPath, 'utf-8'));
        }
    }
    catch {
        /* file not available */
    }
    return content;
}
//# sourceMappingURL=challenge-spec-helpers.js.map