import { FormulaMode } from '@bilig/protocol';
import { appendDirectAggregateColumnReverseEdges, appendFreshDirectAggregateColumnReverseEdgesForRun, canAppendFreshDirectAggregateColumnReverseEdgesForRun, } from './formula-binding-dependency-helpers.js';
import { markFormulaCellBound } from './formula-binding-cell-flags.js';
import { makeUnmanagedCompiledPlan } from './formula-binding-plan-helpers.js';
const EMPTY_U32 = new Uint32Array(0);
export function bindFreshDirectAggregateFormulaRun(args) {
    if ('member' in args.run) {
        assertFreshDirectAggregateFormulaCell(args.serviceArgs, args.run.ownerSheetName, args.run.cellIndex, args.run.member);
        bindFreshDirectAggregateFormulaMember(args.serviceArgs, args.edgeArena, args.formulaMemberCounts, args.trackFormulaSheetIndexes, args.run.sheetId, args.run.ownerSheetName, args.run.cellIndex, args.run.member);
        return;
    }
    if (args.run.cellIndices.length !== args.run.members.length) {
        throw new Error('Expected fresh direct aggregate formula cell index count to match member count');
    }
    const useBulkReverseEdges = canAppendFreshDirectAggregateColumnReverseEdgesForRun(args.serviceArgs.state.workbook, args.run.cellIndices, args.run.members);
    for (let index = 0; index < args.run.members.length; index += 1) {
        const cellIndex = args.run.cellIndices[index];
        const member = args.run.members[index];
        assertFreshDirectAggregateFormulaCell(args.serviceArgs, args.run.ownerSheetName, cellIndex, member);
        bindFreshDirectAggregateFormulaMember(args.serviceArgs, args.edgeArena, args.formulaMemberCounts, args.trackFormulaSheetIndexes, args.run.sheetId, args.run.ownerSheetName, cellIndex, member, !useBulkReverseEdges);
    }
    if (useBulkReverseEdges) {
        appendFreshDirectAggregateColumnReverseEdgesForRun(args.serviceArgs.reverseState.reverseAggregateColumnEdges, args.serviceArgs.state.workbook, args.run.cellIndices, args.run.members);
    }
}
function assertFreshDirectAggregateFormulaCell(serviceArgs, ownerSheetName, cellIndex, member) {
    if ((serviceArgs.state.workbook.cellStore.formulaIds[cellIndex] ?? 0) !== 0) {
        throw new Error('Expected fresh direct aggregate formula cell');
    }
    if (member.aggregateRowStart > member.aggregateRowEnd ||
        member.aggregateColStart > member.aggregateColEnd ||
        (member.aggregateSheetName === ownerSheetName &&
            member.aggregateRowStart <= member.row &&
            member.row <= member.aggregateRowEnd &&
            member.aggregateColStart <= member.col &&
            member.col <= member.aggregateColEnd)) {
        throw new Error('Expected non-recursive fresh direct aggregate formula');
    }
}
function bindFreshDirectAggregateFormulaMember(serviceArgs, edgeArena, formulaMemberCounts, trackFormulaSheetIndexes, sheetId, ownerSheetName, cellIndex, member, appendReverseEdges = true) {
    const directAggregate = buildFreshDirectAggregateDescriptor(serviceArgs, member);
    const runtimeFormula = {
        cellIndex,
        formulaSlotId: 0,
        planId: 0,
        templateId: member.templateId,
        source: member.source,
        compiled: member.compiled,
        plan: makeUnmanagedCompiledPlan(member.source, member.compiled, member.templateId),
        dependencyIndices: EMPTY_U32,
        dependencyEntities: edgeArena.empty(),
        rangeDependencies: EMPTY_U32,
        graphRangeDependencies: EMPTY_U32,
        runtimeProgram: EMPTY_U32,
        constants: member.compiled.constants,
        structuralSourceTransform: undefined,
        programOffset: 0,
        programLength: 0,
        constNumberOffset: 0,
        constNumberLength: member.compiled.constants.length,
        rangeListOffset: 0,
        rangeListLength: 0,
        directLookup: undefined,
        directAggregate,
        directScalar: undefined,
        directCriteria: undefined,
    };
    const formulaSlotId = serviceArgs.state.formulas.set(cellIndex, runtimeFormula);
    runtimeFormula.formulaSlotId = formulaSlotId;
    formulaMemberCounts.increment(sheetId, member.col);
    markFormulaCellBound(serviceArgs.state.workbook.cellStore, cellIndex, member.compiled.mode);
    if (appendReverseEdges) {
        appendDirectAggregateColumnReverseEdges(serviceArgs.reverseState.reverseAggregateColumnEdges, serviceArgs.state.workbook, directAggregate, cellIndex);
    }
    trackFormulaSheetIndexes(cellIndex, ownerSheetName, member.compiled);
    if (member.compiled.mode === FormulaMode.WasmFastPath && member.compiled.program.length > 0) {
        serviceArgs.scheduleWasmProgramSync();
    }
}
function buildFreshDirectAggregateDescriptor(serviceArgs, member) {
    return {
        regionId: serviceArgs.regionGraph.internSingleColumnRegion({
            sheetName: member.aggregateSheetName,
            rowStart: member.aggregateRowStart,
            rowEnd: member.aggregateRowEnd,
            col: member.aggregateColStart,
        }),
        aggregateKind: member.aggregateKind,
        sheetName: member.aggregateSheetName,
        rowStart: member.aggregateRowStart,
        rowEnd: member.aggregateRowEnd,
        col: member.aggregateColStart,
        colEnd: member.aggregateColEnd,
        length: (member.aggregateRowEnd - member.aggregateRowStart + 1) * (member.aggregateColEnd - member.aggregateColStart + 1),
        ...(member.resultOffset !== undefined ? { resultOffset: member.resultOffset } : {}),
    };
}
//# sourceMappingURL=formula-binding-fresh-direct-aggregate-run.js.map