Source: utils/universal/ogc/createVEFLayerConfig.js

import { getDataProductConfig } from "./getDataProductConfig.js";

/**
 * Temporary method to fix issues from indexing
 * FixMe: Fix mapping errors in the index to directly create the resulting object.
 * The index only supports strings inside the "metadata" object right now
 * 
 * @private
 * @param {object} metadata
 * @returns {object} metadata
 */
function fixMetadata_(metadata) {
    for (let i in metadata) {
        if (typeof metadata[i] == "string") {
            metadata[i] = decodeURIComponent(metadata[i]);

            try {
                switch (i) {
                    case "keywords":
                    case "attributes":
                    case "formats":
                    case "crs":
                    case "styles":
                    case "dimensions":
                        metadata[i] = JSON.parse(metadata[i])
                        break;
                }
            } catch (e) { console.log(e) }
        }
    }

    if ("dimensions" in metadata) {
        for (let dim in metadata.dimensions) {
            if (typeof metadata.dimensions[dim]?.values == "string") {
                metadata.dimensions[dim].values = metadata.dimensions[dim].values.trim().split(",");
            }
        }
    }

    return metadata;
}

function geoJsonToBounds_(record) {
    const bounds = {}
    if (record.geometry && (record.geometry.type.toLowerCase() == "polygon") && record.geometry.coordinates.length > 0) {
        record.geometry.coordinates[0].forEach(LngLat => {
            if (isNaN(bounds.minX) || (LngLat[0] < bounds.minX)) bounds.minX = LngLat[0];
            if (isNaN(bounds.maxX) || (LngLat[0] > bounds.maxX)) bounds.maxX = LngLat[0];
            if (isNaN(bounds.minY) || (LngLat[1] < bounds.minY)) bounds.minY = LngLat[1];
            if (isNaN(bounds.maxY) || (LngLat[1] > bounds.maxY)) bounds.maxY = LngLat[1];
        });
    }
    return bounds;
}

/**
 * Create an object that uses the VEF internal layer structure from the capabilitiesParser/catalog metadata
 *
 * @param {object} record metadata from catalog or capabilitiesParser for a layer
 * @returns {object} object containing formatted layer metadata
 */
export async function createVEFLayerConfig(record) {
    const config = {};

    for (let i = 0; i < record.resources.length; ++i) {
        const resource = record.resources[i];
        if (resource.type.toLowerCase() == "service") {
            if (resource.title) config.serviceTitle = resource.title;
            if (resource.uri) config.serviceUrl = resource.uri;
            if (resource.metadata) {
                const metadata = fixMetadata_(resource.metadata);
                if (metadata.type) config.type = metadata.type.toLowerCase();
                if (metadata.name) config.serviceName = metadata.name;
                if (metadata.accessConstraints) config.serviceAccessConstraints = metadata.accessConstraints;
                if (metadata.fees) config.serviceFees = metadata.fees;
                if (metadata.abstract) config.serviceAbstract = metadata.abstract;
                if (metadata.software) config.serviceSoftware = metadata.software;
                if (metadata.version) config.serviceVersion = metadata.version;
                if (metadata.filterType) config.filterType = metadata.filterType;
                if (metadata.keywords) config.serviceKeywords = metadata.keywords;
                if (metadata.crs) config.availableCrs = metadata.crs;
                if (metadata.formats) config.availableFormats = metadata.formats;
            }
            break;
        }
    }

    if (!config.type) return null;

    if (record.title) {
        config.title = record.title;
        config.originalTitle = record.title;
    }
    if (record.description) config.abstract = record.description;
    if (record.uniqueId) config.catalogId = record.uniqueId;

    if (record.metadata) {
        const metadata = fixMetadata_(record.metadata);
        if (metadata.attributes) config.attributeFields = metadata.attributes;
        if (metadata.crs) config.availableCrs = ("availableCrs" in config) ? config.availableCrs.concat(metadata.crs) : metadata.crs;
        if (metadata.name) config.name = metadata.name;
        if (metadata.styles) config.availableStyles = metadata.styles;
        if (metadata.dimensions) config.dimensions = metadata.dimensions;
        if (metadata.keywords) config.keywords = metadata.keywords;
    }

    const dataProductConfig = await getDataProductConfig(config.serviceUrl, config.name);
    const bounds = geoJsonToBounds_(record)

    return Object.assign(config, bounds, dataProductConfig);
}