// Copyright (c) 2009-2026 SAP SE, All Rights Reserved

sap.ui.define([
    "sap/ui/core/Renderer",
    "sap/ui/thirdparty/URI",
    "sap/ushell/appIntegration/ApplicationContainerRenderer",
    "sap/ushell/ApplicationType/systemAlias",
    "sap/ushell/Config",
    "sap/ushell/resources",
    "sap/ushell/utils",
    "sap/ushell/utils/UriParameters"
], (
    Renderer,
    URI,
    ApplicationContainerRenderer,
    systemAliasUtils,
    Config,
    ushellResources,
    ushellUtils,
    UriParameters
) => {
    "use strict";

    let iIframeIdx = 0;

    const IframeApplicationContainerRenderer = Renderer.extend(ApplicationContainerRenderer);

    IframeApplicationContainerRenderer.render = function (oRenderManager, oContainer) {
        if (
            !oContainer.getReadyForRendering()
            || oContainer.getProperty("preparingRendering")
            || !oContainer.getProperty("renderingPrepared")
        ) {
            ApplicationContainerRenderer.render(oRenderManager, oContainer);
            return;
        }

        if (oContainer.getProperty("iframeWithPost")) {
            this._renderIframeWithPOST(oRenderManager, oContainer);
        } else {
            this._renderIframe(oRenderManager, oContainer);
        }

        // mark the rendering as complete, this will suppress any further invalidation
        oContainer.setRenderComplete(true);
    };

    IframeApplicationContainerRenderer._renderIframe = function (oRenderManager, oContainer) {
        const sIframeUrl = oContainer.getProperty("iframeUrl");

        oRenderManager.openStart("iframe", oContainer);
        oRenderManager.accessibilityState(oContainer);
        oRenderManager.attr("src", sIframeUrl);
        oRenderManager.attr("title", ushellResources.i18n.getText("AppilcationContainer.IframeTitle"));
        oRenderManager.attr("data-help-id", oContainer.getDataHelpId());
        oRenderManager.attr("data-sap-ushell-active", oContainer.getActive());
        oRenderManager.attr("data-sap-ushell-iframe-idx", ++iIframeIdx);
        oRenderManager.attr("data-sap-ushell-initial-app-id", oContainer.getInitialAppId());
        oRenderManager.attr("data-sap-ushell-current-app-id", oContainer.getCurrentAppId());
        oRenderManager.attr("data-sap-ushell-stateful-type", oContainer.getStatefulType());
        oRenderManager.attr("data-sap-ushell-framework-id", oContainer.getFrameworkId());
        oRenderManager.class("sapUShellApplicationContainer");
        oRenderManager.style("height", oContainer.getHeight());
        oRenderManager.style("width", oContainer.getWidth());

        if (Config.last("/core/shell/enableFeaturePolicyInIframes") === true) {
            oRenderManager.attr("allow", ushellUtils.getIframeFeaturePolicies());
        }

        oRenderManager.openEnd();
        oRenderManager.close("iframe");
    };

    IframeApplicationContainerRenderer._renderIframeWithPOST = function (oRenderManager, oContainer) {
        this._openPostWrapper(oRenderManager, oContainer);

        // When sending a POST request, we concatenate the string "-iframe" to the 'id' attribute of the <iframe> node.
        // The reason is that in POST request the IFRAME element is a child of a new 'div' element, that holds the
        // original id of the <iframe> node, and in order not to associate them with them with the same id we add this string.
        const sFormId = `${oContainer.getId()}-form`;
        const sIframeId = `${oContainer.getId()}-iframe`;

        const sUrlWithoutSystemAlias = ushellUtils.filterOutParamsFromLegacyAppURL(oContainer.getProperty("iframeUrl"));
        const aParameters = this._getPostParameters(oContainer, sUrlWithoutSystemAlias);
        const oUrls = this._calculatePostUrls(oContainer, sUrlWithoutSystemAlias, aParameters);

        this._renderPostForm(
            oRenderManager,
            sFormId,
            sIframeId,
            oUrls.form,
            `${oContainer.getDataHelpId()}-form`,
            aParameters
        );

        this._renderPostIframe(
            oRenderManager,
            oContainer,
            sIframeId,
            oUrls.iframe,
            oUrls.form,
            `${oContainer.getDataHelpId()}-iframe`
        );

        this._closePostWrapper(oRenderManager);
    };

    IframeApplicationContainerRenderer._openPostWrapper = function (oRenderManager, oContainer) {
        // generate the <div> element that wraps the <form> and the <iframe>
        oRenderManager.openStart("div", oContainer);
        oRenderManager.attr("data-help-id", oContainer.getDataHelpId());
        oRenderManager.attr("data-sap-ushell-active", oContainer.getActive());
        oRenderManager.attr("data-sap-ushell-iframe-app", "true");
        oRenderManager.attr("data-sap-ushell-initial-app-id", oContainer.getInitialAppId());
        oRenderManager.attr("data-sap-ushell-current-app-id", oContainer.getCurrentAppId());
        oRenderManager.attr("data-sap-ushell-stateful-type", oContainer.getStatefulType());
        oRenderManager.attr("data-sap-ushell-framework-id", oContainer.getFrameworkId());
        oRenderManager.class("sapUShellApplicationContainer");
        oRenderManager.style("height", oContainer.getHeight());
        oRenderManager.style("width", oContainer.getWidth());
        oRenderManager.openEnd();
    };

    IframeApplicationContainerRenderer._closePostWrapper = function (oRenderManager) {
        oRenderManager.close("div");
    };

    IframeApplicationContainerRenderer._calculatePostUrls = function (oContainer, sIframeUrlWithoutSystemAlias, aParameters) {
        const sIframeUrlWithSystemAlias = systemAliasUtils.addSystemAlias(sIframeUrlWithoutSystemAlias, oContainer);
        let sFormAction = sIframeUrlWithoutSystemAlias;

        if (oContainer.getIframePostAllParams() && aParameters.length > 1) { // aParameters always contains at least sap-flp-params
            // trim url
            const oIframeUriParams = UriParameters.fromURL(sIframeUrlWithoutSystemAlias);
            const sHint = oIframeUriParams.get("sap-iframe-hint");
            const sKeepAlive = oIframeUriParams.get("sap-keep-alive");
            const oNewURI = new URI(sIframeUrlWithoutSystemAlias).query("");

            if (typeof sHint === "string") {
                oNewURI.addSearch("sap-iframe-hint", sHint);
            }
            if (typeof sKeepAlive === "string") {
                oNewURI.addSearch("sap-keep-alive", sKeepAlive);
            }

            sFormAction = oNewURI.toString();
        }

        return {
            iframe: sIframeUrlWithSystemAlias,
            form: sFormAction
        };
    };

    IframeApplicationContainerRenderer._renderPostForm = function (oRenderManager, sFormId, sIframeId, sFormAction, sFormHelpId, aParameters) {
        oRenderManager.openStart("form");
        oRenderManager.attr("id", sFormId);
        oRenderManager.attr("method", "post");
        oRenderManager.attr("name", sFormId);
        oRenderManager.attr("target", sIframeId);
        oRenderManager.attr("action", sFormAction);
        oRenderManager.attr("data-help-id", sFormHelpId);
        oRenderManager.style("display", "none");
        oRenderManager.openEnd();

        aParameters.forEach((oParam) => {
            oRenderManager.voidStart("input");
            oRenderManager.attr("name", oParam.key);
            oRenderManager.attr("value", oParam.value);
            oRenderManager.voidEnd();
        });

        oRenderManager.close("form");
    };

    IframeApplicationContainerRenderer._renderPostIframe = function (oRenderManager, oContainer, sIframeId, sIframeUrl, sFormAction, sIframeHelpId) {
        oRenderManager.openStart("iframe", sIframeId);
        oRenderManager.attr("name", sIframeId);
        oRenderManager.accessibilityState(oContainer);
        oRenderManager.attr("sap-orig-src", sIframeUrl);
        oRenderManager.attr("title", ushellResources.i18n.getText("AppilcationContainer.IframeTitle"));
        oRenderManager.attr("data-help-id", sIframeHelpId);
        oRenderManager.attr("data-sap-ushell-iframe-idx", ++iIframeIdx);
        oRenderManager.class("sapUShellApplicationContainer");
        oRenderManager.style("height", oContainer.getHeight());
        oRenderManager.style("width", oContainer.getWidth());

        if (Config.last("/core/shell/enableFeaturePolicyInIframes")) {
            oRenderManager.attr("allow", ushellUtils.getIframeFeaturePolicies().replaceAll(";", ` ${new URI(sFormAction).origin()};`));
        }

        oRenderManager.openEnd();
        oRenderManager.close("iframe");
    };

    IframeApplicationContainerRenderer._getPostParameters = function (oContainer, sUrlWithoutSystemAlias) {
        const oIframeUriParams = UriParameters.fromURL(sUrlWithoutSystemAlias);

        const sFLPParams = JSON.stringify(oContainer.getIframePostFlpParams());

        // always include sap-flp-params
        const aResult = [{
            key: "sap-flp-params",
            value: sFLPParams
        }];

        if (!oContainer.getIframePostAllParams()) {
            return aResult;
        }

        let sSapIframeHintVal = "";
        if (oIframeUriParams.has("sap-iframe-hint")) {
            sSapIframeHintVal = oIframeUriParams.get("sap-iframe-hint");
        }

        const oParams = oIframeUriParams.mParams;
        // Verify that it's a WD app (in local FLP or cFLP)
        if (oContainer.getApplicationType() === "TR" || sSapIframeHintVal === "GUI") {
            for (const sKey in oParams) {
                if (sKey === "sap-iframe-hint" || sKey === "sap-keep-alive" || sKey === "sap-flp-params") {
                    continue;
                }
                aResult.push({
                    key: sKey,
                    value: oParams[sKey][0]
                });
            }
        }

        return aResult;
    };

    return IframeApplicationContainerRenderer;
});
