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

/**
 * @fileOverview
 *
 * Exposes functions to create the system context.
 *
 * <p>This is a dependency of ClientSideTargetResolution. Interfaces exposed
 * by this module may change at any time without notice.</p>
 *
 * @version 1.148.1
 */
sap.ui.define([
    "sap/base/util/ObjectPath",
    "sap/ui/thirdparty/URI"
], (
    ObjectPath,
    URI
) => {
    "use strict";

    /**
     * @alias sap.ushell.services.ClientSideTargetResolution.SystemContext
     * @class
     * @classdesc An object representing the context of a system.
     *
     * @private
     */
    class SystemContext {
        #oSystemAlias;

        constructor (oSystemAlias) {
            this.#oSystemAlias = oSystemAlias;
        }

        /**
         * @type {string} The id of the system alias which represents the system in the context of which an application is running.
         *
         * @readonly
         *
         * @private
         */
        get id () {
            return this.#oSystemAlias.id;
        }

        set id (sId) {
            throw new Error("Property 'id' is read-only.");
        }

        /**
         * @type {string} The label of the system alias which represents the system in the context of which an application is running.
         *
         * @readonly
         *
         * @private
         */
        get label () {
            return this.#oSystemAlias.label || this.#oSystemAlias.id;
        }

        set label (sLabel) {
            throw new Error("Property 'label' is read-only.");
        }

        /**
         * A function that returns a URL to issue XHR requests to a service endpoint (existing on a specific system)
         * starting from the path to a service endpoint (existing on all systems).
         * The given path should not be fully qualified.
         * Any fully qualified path will be returned unchanged to support cases where the caller does not control the path (e.g., path argument coming from external data),
         * or a request should be issued to a specific system in the context of the current system.
         * @param {string} sPath The path to a service endpoint (not fully qualified).
         * @returns {string} The fully qualified URL to issue XHR requests.
         *
         * @private
         */
        getFullyQualifiedXhrUrl (sPath) {
            const sPathProtocol = new URI(sPath).protocol();

            // Absolute URLs are not changed
            if (sPathProtocol === "http" || sPathProtocol === "https") {
                return sPath;
            }

            const sProtocol = SystemContext._getProtocol();
            let sPathPrefix = "";

            if (sProtocol === "https") {
                sPathPrefix = ObjectPath.get("https.xhr.pathPrefix", this.#oSystemAlias) || "";
            } else if (sProtocol === "http") {
                sPathPrefix = ObjectPath.get("http.xhr.pathPrefix", this.#oSystemAlias) || "";
            }

            if (sPathPrefix) {
                if (sPath.indexOf("dynamic_dest") > -1) {
                    return sPath;
                }
                return URI.joinPaths(sPathPrefix, sPath).query(new URI(sPath).query()).href();
            }

            return sPath;
        }

        /**
         * A function that returns the value of a property which may or may not be known in the context of the specific system.
         * Given input values are namespaced, e.g., "esearch.provider".
         * This function returns undefined when the property cannot be obtained
         * from the system context. Other types of return values than undefined
         * represent that the property was defined or configured in the context
         * of the system.
         * @param {string} sPropertyKey The key of the property to be obtained from the system context, e.g., "esearch.provider".
         * @returns {*} The value of the property or undefined if the property cannot be obtained from the system context.
         *
         * @private
         */
        getProperty (sPropertyKey) {
            const oAvailableProperties = ObjectPath.get("properties", this.#oSystemAlias) || {};

            return oAvailableProperties[sPropertyKey];
        }

        /**
         * Returns the protocol currently used by the browser.
         * helper for testing
         * @returns {string} The current protocol.
         *
         * @private
         * @since 1.78.0
         */
        static _getProtocol () {
            return new URI(window.location.toString()).protocol();
        }
    }

    return SystemContext;
});
