// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only
import { KERNEL_EVENT_KINDS } from '@lumenflow/control-plane-sdk';
import { buildKernelEventV2 } from './kernel-event-sync/emitters.js';
/**
 * Build the SDK-typed capacity snapshot event. Delegates event_id stamping to
 * the shared emitter factory so replay idempotency works identically to
 * every other conductor kind (WU-2638).
 */
export function buildOrgCapacitySnapshotEvent(input) {
    const options = {};
    if (input.timestamp !== undefined) {
        options.timestamp = input.timestamp;
    }
    if (input.idempotencyKey !== undefined) {
        options.idempotencyKey = input.idempotencyKey;
    }
    const payload = input.maxActiveWorkers !== undefined
        ? {
            kind: KERNEL_EVENT_KINDS.ORG_CAPACITY_SNAPSHOT,
            org_id: input.orgId,
            available_capacity: input.availableCapacity,
            max_active_workers: input.maxActiveWorkers,
        }
        : {
            kind: KERNEL_EVENT_KINDS.ORG_CAPACITY_SNAPSHOT,
            org_id: input.orgId,
            available_capacity: input.availableCapacity,
        };
    const event = buildKernelEventV2(payload, options);
    return event;
}
/**
 * Derive `available_capacity` from a lane-availability map. Each lane with
 * `available: true` contributes one unit; occupied and contaminated lanes
 * contribute zero. Returns 0 for an empty map rather than NaN so downstream
 * arithmetic stays safe.
 */
export function computeAvailableCapacity(availability) {
    let count = 0;
    for (const entry of Object.values(availability)) {
        if (entry.available) {
            count++;
        }
    }
    return count;
}
/**
 * Fire-and-forget capacity snapshot emission. Intended to be called at
 * strategic moments (claim, release, block/unblock, done) and on the sidecar
 * tick; debouncing is left to the caller because the SDK shape does not
 * otherwise carry enough state to hash meaningfully (available_capacity is
 * a single int).
 */
export function emitOrgCapacitySnapshot(options) {
    const availableCapacity = computeAvailableCapacity(options.availability);
    const input = {
        orgId: options.orgId,
        availableCapacity,
    };
    if (options.maxActiveWorkers !== undefined) {
        input.maxActiveWorkers = options.maxActiveWorkers;
    }
    if (options.timestamp !== undefined) {
        input.timestamp = options.timestamp;
    }
    if (options.idempotencyKey !== undefined) {
        input.idempotencyKey = options.idempotencyKey;
    }
    const event = buildOrgCapacitySnapshotEvent(input);
    options.sink(event);
}
//# sourceMappingURL=capacity-snapshot-emitter.js.map