// Copyright 2024 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.
/**
 * Implements the IFR (Instant First-Frame Rendering) on main thread.
 */
import { renderOpcodesIntoElementTemplate } from './render-opcodes.js';
import { render as renderToString } from './render-to-opcodes.js';
import { getReloadVersion } from '../../../core/reload-version.js';
import { profileEnd, profileStart } from '../../debug/profile.js';
import { ElementTemplateLifecycleConstant } from '../../protocol/lifecycle-constant.js';
import { flushInitialElementTemplateListUpdates } from '../list/list.js';
import { insertRootIntoPage, removeRootFromPage } from '../page/page.js';
import { __root } from '../page/root-instance.js';
import { getElementTemplateNativeRef } from '../template/registry.js';
// ET reload reuses the native page, so the main-thread render path owns the
// root refs it appended and can remove only those roots before rebuilding.
let mainThreadRootRefs = [];
function resetMainThreadRootRefs() {
    mainThreadRootRefs = [];
}
function removeMainThreadRootRefs() {
    const rootRefs = mainThreadRootRefs;
    mainThreadRootRefs = [];
    for (const rootRef of rootRefs) {
        removeRootFromPage(rootRef);
    }
}
function renderMainThread() {
    let opcodes;
    profileStart('ReactLynx::renderMainThread');
    try {
        opcodes = renderToString(__root.__jsx, undefined);
    }
    catch (e) {
        lynx.reportError(e);
        opcodes = [];
    }
    finally {
        profileEnd();
    }
    profileStart('ReactLynx::renderOpcodes');
    try {
        const { rootRefs } = renderOpcodesIntoElementTemplate(opcodes);
        for (const rootRef of rootRefs) {
            insertRootIntoPage(rootRef);
        }
        flushInitialListUpdates();
        mainThreadRootRefs = rootRefs;
    }
    finally {
        profileEnd();
    }
    profileStart('ReactLynx::packSerializedETInstance');
    try {
        const instances = [];
        for (const rootRef of mainThreadRootRefs) {
            instances.push(__SerializeElementTemplate(rootRef));
        }
        const payload = {
            instances,
            reloadVersion: getReloadVersion(),
        };
        lynx.getJSContext().dispatchEvent({
            type: ElementTemplateLifecycleConstant.hydrate,
            data: payload,
        });
    }
    finally {
        profileEnd();
    }
}
function flushInitialListUpdates() {
    const results = flushInitialElementTemplateListUpdates();
    for (let index = 0; index < results.length; index += 1) {
        const result = results[index];
        const listRef = getElementTemplateNativeRef(result.uid);
        if (listRef) {
            __SetAttributeOfElementTemplate(listRef, 0, result.attributes, null);
        }
    }
}
export { removeMainThreadRootRefs, renderMainThread, resetMainThreadRootRefs };
//# sourceMappingURL=render-main-thread.js.map