// Copyright 2026 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { getSpreadRefFromValue, queueRefAttrUpdate } from '../prop-adapters/ref.js';
import { __etAttrPlanMap, adaptRefAttrSlot, adaptSpreadAttrSlot } from '../runtime/template/attr-slot-plan.js';
function normalizeAttributeSlots(rawSlots) {
    let normalizedSlots;
    for (let slotIndex = 0; slotIndex < rawSlots.length; slotIndex += 1) {
        const rawSlot = rawSlots[slotIndex];
        if (rawSlot !== undefined) {
            continue;
        }
        normalizedSlots ??= rawSlots.slice();
        normalizedSlots[slotIndex] = null;
    }
    return normalizedSlots ?? rawSlots;
}
function queuePlannedRefAttributeSlotUpdates(handleId, attrPlan, previousRawSlots, nextRawSlots) {
    for (let planIndex = 0; planIndex < attrPlan.length; planIndex += 2) {
        const attrSlotIndex = attrPlan[planIndex];
        const adapter = attrPlan[planIndex + 1];
        if (adapter === adaptRefAttrSlot) {
            queueRefAttrUpdate(previousRawSlots?.[attrSlotIndex], nextRawSlots?.[attrSlotIndex], handleId, attrSlotIndex);
            continue;
        }
        if (adapter === adaptSpreadAttrSlot) {
            const previousSpreadRef = getSpreadRefFromValue(previousRawSlots?.[attrSlotIndex]);
            const nextSpreadRef = getSpreadRefFromValue(nextRawSlots?.[attrSlotIndex]);
            if (previousSpreadRef === undefined && nextSpreadRef === undefined) {
                continue;
            }
            queueRefAttrUpdate(previousSpreadRef, nextSpreadRef ?? null, handleId, attrSlotIndex);
        }
    }
}
export function prepareAttributeSlots(templateKey, handleId, rawSlots, options) {
    const attrPlan = __etAttrPlanMap[templateKey];
    if (!attrPlan || attrPlan.length === 0) {
        return normalizeAttributeSlots(rawSlots);
    }
    const normalizedSlots = normalizeAttributeSlots(rawSlots);
    const preparedSlots = normalizedSlots === rawSlots
        ? rawSlots.slice()
        : normalizedSlots;
    const previousPreparedSlots = options?.previousPreparedSlots;
    const previousRawSlots = options?.previousRawSlots;
    const adapterContext = previousPreparedSlots && previousRawSlots
        ? {
            previousPreparedSlots,
            previousRawSlots,
        }
        : undefined;
    for (let planIndex = 0; planIndex < attrPlan.length; planIndex += 2) {
        const attrSlotIndex = attrPlan[planIndex];
        const adapter = attrPlan[planIndex + 1];
        const rawValue = rawSlots[attrSlotIndex];
        preparedSlots[attrSlotIndex] = adapter(handleId, attrSlotIndex, rawValue, adapterContext);
    }
    return preparedSlots;
}
export function queueRefAttributeSlotUpdates(templateKey, handleId, previousRawSlots, nextRawSlots) {
    const attrPlan = __etAttrPlanMap[templateKey];
    if (!attrPlan || attrPlan.length === 0) {
        return;
    }
    queuePlannedRefAttributeSlotUpdates(handleId, attrPlan, previousRawSlots, nextRawSlots);
}
//# sourceMappingURL=attr-slots.js.map