"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get resolver () {
        return resolver;
    },
    get sortResourcesInDependencyOrder () {
        return sortResourcesInDependencyOrder;
    }
});
const _constants = require("@tamanu/constants");
const _resources = require("@tamanu/shared/utils/fhir/resources");
const _sleepAsync = require("@tamanu/utils/sleepAsync");
const buildDependencyMap = (resources)=>resources.reduce((acc, resource)=>{
        acc[resource.name] = resource.referencedResources.map((r)=>r.name);
        return acc;
    }, {});
const sortResourcesInDependencyOrder = (resources)=>{
    const dependencyMap = buildDependencyMap(resources);
    const sorted = [];
    const stillToSort = new Map(resources.map((r)=>[
            r.name,
            r
        ]));
    let lastSize = -1;
    while(stillToSort.size > 0){
        if (stillToSort.size === lastSize) {
            // If the map size hasn't changed, we've made no progress and are in a loop.
            const remaining = [
                ...stillToSort.keys()
            ].join(', ');
            throw new Error(`Circular dependency detected: ${remaining}`);
        }
        lastSize = stillToSort.size;
        for (const [modelName, model] of stillToSort){
            const dependsOn = dependencyMap[modelName] || [];
            const hasUnresolvedDependencies = dependsOn.some((depName)=>stillToSort.has(depName));
            if (!hasUnresolvedDependencies) {
                sorted.push(model);
                stillToSort.delete(modelName);
            }
        }
    }
    return sorted;
};
async function resolver(_, { log, sequelize, models }) {
    await (0, _sleepAsync.sleepAsync)(3000); // sleep for 3 seconds to allow materialisation jobs to complete
    const materialisableResources = (0, _resources.resourcesThatCanDo)(models, _constants.FHIR_INTERACTIONS.INTERNAL.MATERIALISE);
    log.debug('Starting resolve');
    await sequelize.transaction(async ()=>{
        const sortedResources = sortResourcesInDependencyOrder(materialisableResources);
        for (const resource of sortedResources){
            await resource.resolveUpstreams();
        }
    });
    log.debug('Done resolving');
}

//# sourceMappingURL=resolver.js.map