// Copyright (c) 2009-2026 SAP SE, All Rights Reserved
sap.ui.define([
    "sap/base/Log",
    "sap/base/i18n/Formatting",
    "sap/base/util/deepExtend",
    "sap/base/util/ObjectPath",
    "sap/ui/thirdparty/jquery",
    "sap/ushell/User"
], (
    Log,
    Formatting,
    deepExtend,
    ObjectPath,
    jQuery,
    User
) => {
    "use strict";
    function ContainerAdapter (oSystem, sParameter, oConfig) {
        let oUser;
        let sLogoutUrl;
        let sLogoutMethod;
        let sCsrfTokenUrl;
        let sKeepAliveURL;
        let sKeepAliveMethod;

        function setSAPUI5Settings (oSettings) {
            if (oSettings.sapDateFormat) {
                Formatting.setABAPDateFormat(oSettings.sapDateFormat);
            }
            if (oSettings.sapDateCalendarCustomizing) {
                Formatting.setCustomIslamicCalendarData(oSettings.sapDateCalendarCustomizing);
            }
            if (oSettings.sapNumberFormat) {
                Formatting.setABAPNumberFormat(oSettings.sapNumberFormat);
            }
            if (oSettings.sapTimeFormat) {
                Formatting.setABAPTimeFormat(oSettings.sapTimeFormat);
            }
            if (typeof oSettings.currencyFormats === "object") {
                Formatting.addCustomCurrencies(oSettings.currencyFormats);
            }
        }

        this.load = function () {
            sLogoutUrl = ObjectPath.get("config.systemProperties.logoutUrl", oConfig);
            sLogoutMethod = ObjectPath.get("config.systemProperties.logoutMethod", oConfig) || "GET";
            sCsrfTokenUrl = ObjectPath.get("config.systemProperties.csrfTokenUrl", oConfig);
            sKeepAliveURL = ObjectPath.get("config.systemProperties.sessionKeepAlive.url", oConfig);
            sKeepAliveMethod = ObjectPath.get("config.systemProperties.sessionKeepAlive.method", oConfig);

            // prepare user object
            const userInfo = deepExtend(
                {id: ""},
                ObjectPath.get("config.userProfile.defaults", oConfig)
            );
            oUser = new User(userInfo);
            setSAPUI5Settings(userInfo);

            return new jQuery.Deferred().resolve().promise();
        };

        this.getSystem = function () {
            return oSystem;
        };

        this.getUser = function () {
            return oUser;
        };

        this._getLogoutUrl = function () {
            return sLogoutUrl;
        };

        this._setWindowLocation = function (data) {
            window.location.href = data;
        };

        this.logout = function () {
            const oDeferred = new jQuery.Deferred();
            const that = this;

            if (sLogoutMethod === "POST") {
                Log.info("performing logout from system via POST", undefined, "sap.ushell.appRuntime.ui5.services.adapters.ContainerAdapter::logout");
                jQuery.ajax({
                    type: "HEAD",
                    url: sCsrfTokenUrl,
                    headers: {
                        "X-CSRF-Token": "Fetch"
                    },
                    success: function (oData, oStatus, oXhr) {
                        jQuery.ajax({
                            type: "POST",
                            url: sLogoutUrl,
                            headers: {
                                "X-CSRF-Token": oXhr.getResponseHeader("X-CSRF-Token")
                            },
                            success: function (data) {
                                that._setWindowLocation(data);
                                oDeferred.resolve();
                            },
                            error: function () {
                                Log.error("Logging out via POST failed",
                                    undefined, "sap.ushell.appRuntime.ui5.services.adapters.ContainerAdapter::logout");
                                oDeferred.resolve();
                            }
                        });
                    },
                    error: function () {
                        Log.error(`fetching X-CSRF-Token for logout via POST failed for system: ${oSystem.getAlias()}`,
                            undefined, "sap.ushell.appRuntime.ui5.services.adapters.ContainerAdapter::logout");
                        oDeferred.resolve();
                    }
                });
            } else {
                try {
                    if (typeof sLogoutUrl === "string" && sLogoutUrl.length > 0) {
                        this._logoutViaHiddenIFrame(oDeferred, sLogoutUrl);
                        // resolve after 4 seconds if no response came from the logout iframe
                        setTimeout(oDeferred.resolve, 4000);
                    } else {
                        oDeferred.resolve();
                    }
                } catch (oError) {
                    Log.error(
                        `logout from iframe ${document.URL} failed`,
                        oError,
                        "sap.ushell.appRuntime.ui5.SessionHandlerAgent"
                    );
                    oDeferred.resolve();
                }
            }

            return oDeferred.promise();
        };

        this._logoutViaHiddenIFrame = function (oDeferred, sUrl) {
            const oFrame = document.createElement("iframe");
            const sSafeUrl = sUrl.replace(/"/g, "\\\"");

            window.addEventListener("message", (oEvent) => {
                if ((oEvent.data && oEvent.data.url) === sUrl) {
                    oDeferred.resolve();
                }
            });

            oFrame.style.visibility = "hidden";
            oFrame.setAttribute("src", sUrl);

            function onload () {
                this.contentWindow.parent.postMessage({
                    url: sSafeUrl,
                    request_id: "dummy-logout-id"
                }, "*");
            }

            oFrame.addEventListener("load", onload);
            oFrame.addEventListener("error", onload);

            document.body.appendChild(oFrame);
        };

        this.sessionKeepAlive = function () {
            if (typeof sKeepAliveURL === "string" && sKeepAliveURL.length > 0 &&
                typeof sKeepAliveMethod === "string" && sKeepAliveMethod.length > 0) {
                const oXHR = new XMLHttpRequest();
                oXHR.open(sKeepAliveMethod, sKeepAliveURL, /* async=*/true);

                oXHR.onreadystatechange = function () {
                    if (this.readyState === /* DONE */4) {
                        Log.debug("Server session was extended");
                    }
                };

                oXHR.send();
            }
        };
    }

    return ContainerAdapter;
}, /* bExport= */ true);
