import { getResourceUrl } from '@module-federation/sdk';
import { a as getSignalFromManifest } from './runtime-utils.esm.mjs';
import { M as MFDataPrefetch } from './prefetch.esm.mjs';
import { l as logger } from './index.esm2.mjs';
import { S as SHARED_STRATEGY } from './constant.esm.mjs';

const loadingArray = [];
let sharedFlag = SHARED_STRATEGY;
// eslint-disable-next-line max-lines-per-function
const prefetchPlugin = ()=>({
        name: 'data-prefetch-runtime-plugin',
        initContainer (options) {
            const { remoteSnapshot, remoteInfo, id, origin } = options;
            const snapshot = remoteSnapshot;
            const { name } = remoteInfo;
            const prefetchOptions = {
                name,
                remote: remoteInfo,
                origin,
                remoteSnapshot: snapshot
            };
            const signal = getSignalFromManifest(snapshot);
            if (!signal) {
                return options;
            }
            if (sharedFlag !== SHARED_STRATEGY) {
                throw new Error(`[Module Federation Data Prefetch]: If you want to use data prefetch, the shared strategy must be 'loaded-first'`);
            }
            const instance = MFDataPrefetch.getInstance(name) || new MFDataPrefetch(prefetchOptions);
            let prefetchUrl;
            // @ts-expect-error
            if (snapshot.prefetchEntry) {
                // @ts-expect-error
                prefetchUrl = getResourceUrl(snapshot, snapshot.prefetchEntry);
            }
            const exist = loadingArray.find((loading)=>loading.id === id);
            if (exist) {
                return options;
            }
            const promise = instance.loadEntry(prefetchUrl).then(async ()=>{
                const projectExports = instance.getProjectExports();
                if (projectExports instanceof Promise) {
                    await projectExports;
                }
                return Promise.resolve().then(()=>{
                    const exports = instance.getExposeExports(id);
                    logger.info(`1. Start Prefetch initContainer: ${id} - ${performance.now()}`);
                    const result = Object.keys(exports).map((k)=>{
                        const value = instance.prefetch({
                            id,
                            functionId: k
                        });
                        const functionId = k;
                        return {
                            value,
                            functionId
                        };
                    });
                    return result;
                });
            });
            loadingArray.push({
                id,
                promise
            });
            return options;
        },
        afterResolve (options) {
            const { remoteSnapshot, remoteInfo, id, origin } = options;
            const snapshot = remoteSnapshot;
            const { name } = remoteInfo;
            const prefetchOptions = {
                name,
                remote: remoteInfo,
                origin,
                remoteSnapshot: snapshot
            };
            const signal = getSignalFromManifest(snapshot);
            if (!signal) {
                return options;
            }
            const inited = loadingArray.some((info)=>info.id === id);
            if (!inited) {
                return options;
            }
            if (sharedFlag !== SHARED_STRATEGY) {
                throw new Error(`[Module Federation Data Prefetch]: If you want to use data prefetch, the shared strategy must be 'loaded-first'`);
            }
            const instance = MFDataPrefetch.getInstance(name) || new MFDataPrefetch(prefetchOptions);
            let prefetchUrl;
            // @ts-expect-error
            if (snapshot.prefetchEntry) {
                // @ts-expect-error
                prefetchUrl = getResourceUrl(snapshot, snapshot.prefetchEntry);
            }
            const index = loadingArray.findIndex((loading)=>loading.id === id);
            // clear cache
            if (index !== -1) {
                loadingArray.splice(index, 1);
            }
            const promise = instance.loadEntry(prefetchUrl).then(async ()=>{
                const projectExports = instance.getProjectExports();
                if (projectExports instanceof Promise) {
                    await projectExports;
                }
                return Promise.resolve().then(()=>{
                    const exports = instance.getExposeExports(id);
                    logger.info(`1. Start Prefetch afterResolve: ${id} - ${performance.now()}`);
                    const result = Object.keys(exports).map((k)=>{
                        const value = instance.prefetch({
                            id,
                            functionId: k
                        });
                        const functionId = k;
                        return {
                            value,
                            functionId
                        };
                    });
                    return result;
                });
            });
            loadingArray.push({
                id,
                promise
            });
            return options;
        },
        async onLoad (options) {
            var _loadingArray_find;
            const { remote, id } = options;
            const { name } = remote;
            const promise = (_loadingArray_find = loadingArray.find((loading)=>loading.id === id)) == null ? void 0 : _loadingArray_find.promise;
            if (promise) {
                const prefetch = await promise;
                const prefetchValue = prefetch.map((result)=>result.value);
                await Promise.all(prefetchValue);
                const instance = MFDataPrefetch.getInstance(name);
                prefetch.forEach((result)=>{
                    const { value, functionId } = result;
                    instance.memorize(id + functionId, value);
                });
            }
            return options;
        },
        beforeLoadShare (options) {
            const shareInfo = options.shareInfo;
            sharedFlag = (shareInfo == null ? void 0 : shareInfo.strategy) || sharedFlag;
            return options;
        }
    });

export { prefetchPlugin as default, prefetchPlugin };
