import { UmbControllerBase } from '../../../../../libs/class-api/index.js';
import { createExtensionApi } from '../../../../../libs/extension-api/index.js';
import { umbExtensionsRegistry } from '../../../extension-registry/index.js';
export class UmbDataSourceDataMappingResolver extends UmbControllerBase {
    #apiCache = new Map();
    async resolve(forDataSource, forDataModel) {
        if (!forDataSource) {
            throw new Error('data source identifier is required');
        }
        if (!forDataModel) {
            throw new Error('data identifier is required');
        }
        const manifest = this.#getManifestWithBestFit(forDataSource, forDataModel);
        if (!manifest) {
            return undefined;
        }
        // Check the cache before creating a new instance
        if (this.#apiCache.has(manifest.alias)) {
            return this.#apiCache.get(manifest.alias);
        }
        const dataMapping = await createExtensionApi(this, manifest);
        if (!dataMapping) {
            return undefined;
        }
        if (!dataMapping.map) {
            throw new Error('Data Mapping does not have a map method.');
        }
        // Cache the api instance for future use
        this.#apiCache.set(manifest.alias, dataMapping);
        return dataMapping;
    }
    #getManifestWithBestFit(forDataSource, forDataModel) {
        const supportedManifests = this.#getSupportedManifests(forDataSource, forDataModel);
        if (!supportedManifests.length) {
            return undefined;
        }
        // Pick the manifest with the highest priority
        // TODO: This should have been handled in the extension registry, but until then we do it here: [NL]
        return supportedManifests.sort((a, b) => (b.weight || 0) - (a.weight || 0))[0];
    }
    #getSupportedManifests(forDataSource, forDataModel) {
        const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataSourceDataMapping', (manifest) => {
            return manifest.forDataSource === forDataSource && manifest.forDataModel === forDataModel;
        });
        return supportedManifests;
    }
}
