"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.collectMetadata = collectMetadata;
exports.accumulateMetadata = accumulateMetadata;
var _defaultMetadata = require("./default-metadata");
var _resolveOpengraph = require("./resolvers/resolve-opengraph");
var _resolveTitle = require("./resolvers/resolve-title");
var _utils = require("./generate/utils");
var _isClientReference = require("../../build/is-client-reference");
var _appDirModule = require("../../server/lib/app-dir-module");
var _interopDefault = require("../interop-default");
var _resolveBasics = require("./resolvers/resolve-basics");
var _resolveIcons = require("./resolvers/resolve-icons");
// Merge the source metadata into the resolved target metadata.
function merge(target, source, templateStrings) {
    const metadataBase = source.metadataBase || null;
    for(const key_ in source){
        const key = key_;
        switch(key){
            case "title":
                {
                    if (source.title) {
                        target.title = source.title;
                        (0, _resolveTitle).mergeTitle(target, templateStrings.title);
                    }
                    break;
                }
            case "alternates":
                {
                    target.alternates = (0, _resolveBasics).resolveAlternates(source.alternates, metadataBase);
                    break;
                }
            case "openGraph":
                {
                    target.openGraph = (0, _resolveOpengraph).resolveOpenGraph(source.openGraph, metadataBase);
                    if (target.openGraph) {
                        (0, _resolveTitle).mergeTitle(target.openGraph, templateStrings.openGraph);
                    }
                    break;
                }
            case "twitter":
                {
                    target.twitter = (0, _resolveOpengraph).resolveTwitter(source.twitter, metadataBase);
                    if (target.twitter) {
                        (0, _resolveTitle).mergeTitle(target.twitter, templateStrings.twitter);
                    }
                    break;
                }
            case "verification":
                target.verification = (0, _resolveBasics).resolveVerification(source.verification);
                break;
            case "viewport":
                {
                    target.viewport = (0, _resolveBasics).resolveViewport(source.viewport);
                    break;
                }
            case "icons":
                {
                    target.icons = (0, _resolveIcons).resolveIcons(source.icons);
                    break;
                }
            case "appleWebApp":
                target.appleWebApp = (0, _resolveBasics).resolveAppleWebApp(source.appleWebApp);
                break;
            case "appLinks":
                target.appLinks = (0, _resolveBasics).resolveAppLinks(source.appLinks);
                break;
            case "robots":
                {
                    target.robots = (0, _resolveBasics).resolveRobots(source.robots);
                    break;
                }
            case "archives":
            case "assets":
            case "bookmarks":
            case "keywords":
            case "authors":
                {
                    // FIXME: type inferring
                    // @ts-ignore
                    target[key] = (0, _utils).resolveAsArrayOrUndefined(source[key]) || null;
                    break;
                }
            // directly assign fields that fallback to null
            case "applicationName":
            case "description":
            case "generator":
            case "themeColor":
            case "creator":
            case "publisher":
            case "category":
            case "classification":
            case "referrer":
            case "colorScheme":
            case "itunes":
            case "formatDetection":
                // @ts-ignore TODO: support inferring
                target[key] = source[key] || null;
                break;
            case "other":
                target.other = Object.assign({}, target.other, source.other);
                break;
            case "metadataBase":
                target.metadataBase = metadataBase;
                break;
            default:
                break;
        }
    }
}
async function getDefinedMetadata(mod, props) {
    // Layer is a client component, we just skip it. It can't have metadata
    // exported. Note that during our SWC transpilation, it should check if
    // the exports are valid and give specific error messages.
    if ((0, _isClientReference).isClientReference(mod)) {
        return null;
    }
    if (mod.metadata && mod.generateMetadata) {
        throw new Error(`${mod.path} is exporting both metadata and generateMetadata which is not supported. If all of the metadata you want to associate to this page/layout is static use the metadata export, otherwise use generateMetadata. File: ${mod.path}`);
    }
    return (mod.generateMetadata ? (parent)=>mod.generateMetadata(props, parent) : mod.metadata) || null;
}
async function collectStaticFsBasedIcons(metadata, type) {
    if (!(metadata == null ? void 0 : metadata[type])) return undefined;
    const iconPromises = metadata[type].map(// TODO-APP: share the typing between next-metadata-image-loader and here
    async (iconResolver)=>(0, _interopDefault).interopDefault(await iconResolver()));
    return (iconPromises == null ? void 0 : iconPromises.length) > 0 ? await Promise.all(iconPromises) : undefined;
}
async function resolveStaticMetadata(components) {
    const { metadata  } = components;
    if (!metadata) return null;
    const [icon, apple] = await Promise.all([
        collectStaticFsBasedIcons(metadata, "icon"),
        collectStaticFsBasedIcons(metadata, "apple"), 
    ]);
    const icons = {};
    if (icon) icons.icon = icon;
    if (apple) icons.apple = apple;
    return {
        icons
    };
}
async function collectMetadata(loaderTree, props, array) {
    const mod = await (0, _appDirModule).getLayoutOrPageModule(loaderTree);
    const staticFilesMetadata = await resolveStaticMetadata(loaderTree[2]);
    const metadataExport = mod ? await getDefinedMetadata(mod, props) : null;
    array.push([
        metadataExport,
        staticFilesMetadata
    ]);
}
async function accumulateMetadata(metadataItems) {
    const resolvedMetadata = (0, _defaultMetadata).createDefaultMetadata();
    let parentPromise = Promise.resolve(resolvedMetadata);
    for (const item of metadataItems){
        const [metadataExport, staticFilesMetadata] = item;
        const layerMetadataPromise = Promise.resolve(typeof metadataExport === "function" ? metadataExport(parentPromise) : metadataExport);
        parentPromise = parentPromise.then((resolved)=>{
            return layerMetadataPromise.then((exportedMetadata)=>{
                const metadata = exportedMetadata || staticFilesMetadata;
                if (metadata) {
                    var ref, ref1, ref2, ref3, ref4;
                    // Overriding the metadata if static files metadata is present
                    merge(resolved, {
                        ...metadata,
                        ...staticFilesMetadata
                    }, {
                        title: ((ref = resolved.title) == null ? void 0 : ref.template) || null,
                        openGraph: ((ref1 = resolved.openGraph) == null ? void 0 : (ref2 = ref1.title) == null ? void 0 : ref2.template) || null,
                        twitter: ((ref3 = resolved.twitter) == null ? void 0 : (ref4 = ref3.title) == null ? void 0 : ref4.template) || null
                    });
                }
                return resolved;
            });
        });
    }
    return await parentPromise;
}

//# sourceMappingURL=resolve-metadata.js.map