/**
 * Test helper utilities for working with diagnostics.
 */

/**
 * Finds diagnostics matching a substring.
 * @param {Array} diagnostics - Array of diagnostics
 * @param {string} substring - Message substring to search for
 * @returns {Array} Matching diagnostics
 */
function findDiagnosticsWithMessage(diagnostics, substring) {
    return diagnostics.filter(d => d.message.includes(substring));
}

/**
 * Asserts that a diagnostic exists with a specific message.
 * @param {Array} diagnostics - Array of diagnostics
 * @param {string} substring - Message substring
 * @param {string} customMessage - Optional custom assertion message
 */
function assertHasDiagnostic(diagnostics, substring, customMessage) {
    const matching = findDiagnosticsWithMessage(diagnostics, substring);
    if (matching.length === 0) {
        const messages = diagnostics.map(d => `  - "${d.message}"`).join('\n');
        throw new Error(
            customMessage || 
            `Expected diagnostic containing "${substring}" but found none.\nActual diagnostics:\n${messages}`
        );
    }
}

/**
 * Asserts that no diagnostic exists with a specific message.
 * @param {Array} diagnostics - Array of diagnostics
 * @param {string} substring - Message substring
 * @param {string} customMessage - Optional custom assertion message
 */
function assertNoDiagnostic(diagnostics, substring, customMessage) {
    const matching = findDiagnosticsWithMessage(diagnostics, substring);
    if (matching.length > 0) {
        const messages = matching.map(d => `  - "${d.message}"`).join('\n');
        throw new Error(
            customMessage || 
            `Expected NO diagnostic containing "${substring}" but found ${matching.length}:\n${messages}`
        );
    }
}

/**
 * Asserts diagnostic count.
 * @param {Array} diagnostics - Array of diagnostics
 * @param {number} expectedCount - Expected count
 * @param {string} customMessage - Optional custom assertion message
 */
function assertDiagnosticCount(diagnostics, expectedCount, customMessage) {
    if (diagnostics.length !== expectedCount) {
        const messages = diagnostics.map(d => `  - "${d.message}"`).join('\n');
        throw new Error(
            customMessage || 
            `Expected ${expectedCount} diagnostic(s) but found ${diagnostics.length}:\n${messages}`
        );
    }
}

/**
 * Gets diagnostic message at a specific line.
 * @param {Array} diagnostics - Array of diagnostics
 * @param {number} line - Line number
 * @returns {Array} Diagnostics on that line
 */
function getDiagnosticsAtLine(diagnostics, line) {
    return diagnostics.filter(d => d.range.start.line === line);
}

export {
    findDiagnosticsWithMessage,
    assertHasDiagnostic,
    assertNoDiagnostic,
    assertDiagnosticCount,
    getDiagnosticsAtLine
};
