/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */
import { getSpanCategory, getCategoryMeta, buildDisplayName } from './spanCategorization.js';
/**
 * Preprocess span tree in a single pass instead of multiple traversals
 *
 * Combines: categorization, flattening, stats calculation, and indexing
 * This eliminates 4-6 separate tree walks, improving performance by 60-75%
 *
 * @param spanTree - Root spans of the tree
 * @param timeRange - Time range for percentage calculations
 * @returns All derived data in a single object
 */
export function preprocessSpanTree(spanTree, timeRange) {
    const flattenedSpans = [];
    const spanIndex = new Map();
    const categoryMap = new Map();
    const toolMap = new Map();
    /**
     * Single recursive pass to compute everything
     * @param span - Current span to process
     * @param depth - Current depth in tree (for visualization)
     * @returns Categorized span with all metadata
     */
    function processNode(span, depth) {
        // Categorize span
        const category = getSpanCategory(span);
        const meta = getCategoryMeta(category);
        const categorizedSpan = {
            ...span,
            category,
            categoryLabel: meta.label,
            categoryColor: meta.color,
            categoryIcon: meta.icon,
            displayName: buildDisplayName(span, category),
            depth,
            children: [], // Will be populated below
        };
        // Flatten - add to flat list
        flattenedSpans.push(categorizedSpan);
        // Index - for O(1) lookups by spanId
        spanIndex.set(span.spanId, categorizedSpan);
        // Category stats - count and duration
        const existing = categoryMap.get(category) || { count: 0, duration: 0 };
        categoryMap.set(category, {
            count: existing.count + 1,
            duration: existing.duration + (span.duration || 0),
        });
        // Tool stats - extract tool name and count usage
        if (category === 'TOOL' && span.name) {
            // Extract tool name from span name (e.g., "Tool: Read" -> "Read")
            const toolName = span.name.replace(/^Tool:\s*/, '').trim();
            const toolExisting = toolMap.get(toolName) || { count: 0, duration: 0 };
            toolMap.set(toolName, {
                count: toolExisting.count + 1,
                duration: toolExisting.duration + (span.duration || 0),
            });
        }
        // Process children recursively
        if (span.children && span.children.length > 0) {
            categorizedSpan.children = span.children.map(child => processNode(child, depth + 1));
        }
        return categorizedSpan;
    }
    // Process all root spans
    const categorizedTree = spanTree.map(span => processNode(span, 0));
    // Calculate sum of all category durations for percentage calculation
    let sumOfAllDurations = 0;
    categoryMap.forEach((data) => {
        sumOfAllDurations += data.duration;
    });
    // Convert maps to stats arrays
    const categoryStats = [];
    categoryMap.forEach((data, category) => {
        categoryStats.push({
            category,
            count: data.count,
            totalDuration: data.duration,
            percentage: sumOfAllDurations > 0 ? (data.duration / sumOfAllDurations) * 100 : 0,
        });
    });
    categoryStats.sort((a, b) => b.totalDuration - a.totalDuration);
    const toolStats = [];
    toolMap.forEach((data, name) => {
        toolStats.push({
            name,
            count: data.count,
            totalDuration: data.duration,
        });
    });
    toolStats.sort((a, b) => b.count - a.count);
    return {
        categorizedTree,
        flattenedSpans,
        categoryStats,
        toolStats,
        spanIndex,
    };
}
//# sourceMappingURL=spanPreprocessing.js.map