/**
 * @fileoverview Pure, framework-agnostic helpers for the Knowledge Hub
 * **Feature Pipelines** resource component's AI-agent integration.
 *
 * Free of Angular / component dependencies so they can be unit-tested in
 * isolation. The component supplies its `FeaturePipelineSummary[]` snapshot and
 * these helpers shape the deep agent context + resolve agent-supplied pipeline
 * references (by id → name → contains).
 *
 * 🔒 SAFETY: these helpers only PROJECT state and RESOLVE references — no
 * mutation, no side effects.
 */
import { boundNameList, AGENT_CONTEXT_NAME_LIST_CAP } from '../../../shared/agent-tool-validation';
/**
 * Resolve a pipeline reference the way the agent expresses it — by id (exact,
 * case-insensitive) → name (exact, case-insensitive) → name *contains*
 * (case-insensitive). Pure + deterministic.
 *
 * @returns the matched pipeline, or null on a miss.
 */
export function resolvePipeline(input, pipelines) {
    const needle = input.trim().toLowerCase();
    if (!needle)
        return null;
    const byID = pipelines.find(p => p.ID.toLowerCase() === needle);
    if (byID)
        return byID;
    const byName = pipelines.find(p => p.Name.toLowerCase() === needle);
    if (byName)
        return byName;
    return pipelines.find(p => p.Name.toLowerCase().includes(needle)) ?? null;
}
/** Build a tolerant "no pipeline matches" error listing a bounded sample of names. */
export function buildPipelineNotFoundError(input, available) {
    const sample = boundNameList(available, 10).join(', ');
    const more = available.length > 10 ? ` (+${available.length - 10} more)` : '';
    return `No feature pipeline matches "${input}". Available pipelines: ${sample}${more}.`;
}
/** Count pipelines by their normalized last-run status. */
function countByRunStatus(pipelines, status) {
    return pipelines.filter(p => p.LastRunStatus === status).length;
}
/**
 * Build the agent-visible context for the Feature Pipelines surface. Publishes
 * deep counts (by status, by run-outcome, by work-type), the active search,
 * which pipelines are running, and a **bounded** structured list of the filtered
 * pipelines (name · target entity · output attribute · status · last-run) so the
 * agent can pick one to run or open. A companion truncation flag tells it when
 * the list is capped.
 */
export function buildFeaturePipelinesAgentContext(input) {
    const all = input.AllPipelines;
    const filtered = input.FilteredPipelines;
    const runningNames = all.filter(p => input.RunningIDs.has(p.ID)).map(p => p.Name);
    const ctx = {
        IsLoading: input.IsLoading,
        PipelineCount: all.length,
        FilteredPipelineCount: filtered.length,
        SearchQuery: input.SearchQuery,
        // By Record-Process status
        ActiveCount: all.filter(p => p.Status === 'Active').length,
        DisabledCount: all.filter(p => p.Status === 'Disabled').length,
        DraftCount: all.filter(p => p.Status === 'Draft').length,
        // By last-run outcome
        NeverRunCount: countByRunStatus(all, 'Never'),
        CompletedCount: countByRunStatus(all, 'Completed'),
        FailedCount: countByRunStatus(all, 'Failed'),
        RunningStatusCount: countByRunStatus(all, 'Running'),
        // In-flight runs (this session)
        RunningCount: runningNames.length,
        RunningPipelineNames: boundNameList(runningNames),
        // Bounded structured view of what's on screen
        VisiblePipelineNames: boundNameList(filtered.map(p => p.Name)),
        Pipelines: filtered.slice(0, AGENT_CONTEXT_NAME_LIST_CAP).map(p => ({
            Name: p.Name,
            TargetEntity: p.TargetEntity,
            OutputAttribute: p.OutputAttribute,
            Status: p.Status,
            WorkType: p.WorkType,
            LastRunStatus: p.LastRunStatus,
        })),
    };
    if (filtered.length > AGENT_CONTEXT_NAME_LIST_CAP) {
        ctx['PipelinesTruncated'] = true;
    }
    return ctx;
}
//# sourceMappingURL=feature-pipelines-agent-context.js.map