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

/**
 * @file The modules base API providing common functionality for all module APIs.
 */
sap.ui.define([
    "sap/base/util/ObjectPath"
], (
    ObjectPath
) => {
    "use strict";

    /**
     * The base API class for all module APIs.
     *
     * @since 1.142.0
     * @private
     */
    class BaseAPI {
        /**
         * @type {object} The configuration object for the module.
         */
        #oConfig;
        /**
         * @type {object} An object to store property bindings to models.
         * The keys are property aliases, the values are objects containing the model and the binding.
         * @example
         * {
         *   "propertyAlias1": {
         *     model: oModel,
         *     binding: oBinding
         *   },
         *   "propertyAlias2": {
         *     model: oModel2,
         *     binding: oBinding2
         *   }
         * }
         */
        #oPropertyBindings = {};

        /**
         * Creates a new instance of the BaseAPI class.
         *
         * @param {object} [oConfig={}] The configuration object for the module.
         *
         * @since 1.142.0
         * @private
         */
        constructor (oConfig = {}) {
            this.#oConfig = oConfig;
        }

        /**
         * Gets a configuration value by its path.
         * @param {string} sPath The path to the configuration value, using dot notation for nested properties.
         * @returns {any} The configuration value at the given path, or undefined if not found.
         * If the path is empty, the entire configuration object is returned.
         *
         * @since 1.142.0
         * @private
         */
        getConfigValue (sPath) {
            return ObjectPath.get(sPath, this.#oConfig);
        }

        /**
         * Binds a property of the module API to a model property.
         * When the model property changes, the provided setter callback is called with the new value.
         *
         * @param {string} sPath The absolute path to the property in the model.
         * @param {sap.ui.model.Model} oModel The model to bind to.
         * @param {string} sPropertyAlias The alias for the property in the module API.
         * @param {function} fnChangeHandler The callback function to call when the model property changes.
         *
         * @since 1.142.0
         * @private
         */
        bindModelProperty (sPath, oModel, sPropertyAlias, fnChangeHandler) {
            const oBinding = oModel.bindProperty(sPath);
            oBinding.attachChange(() => {
                fnChangeHandler(oBinding.getValue());
            });
            // store the binding to be able to unbind it later
            this.#oPropertyBindings[sPropertyAlias] = {
                model: oModel,
                binding: oBinding
            };
            // initialize the property with the current value
            fnChangeHandler(oBinding.getValue());
        }

        /**
         * Unbinds a property of the module API from its model.
         * @param {string} sPropertyAlias The alias for the property in the module API to unbind.
         * @since 1.142.0
         * @private
         */
        unbindModelProperty (sPropertyAlias) {
            const oModelData = this.#oPropertyBindings[sPropertyAlias];
            if (oModelData) {
                oModelData.binding.destroy();
                delete this.#oPropertyBindings[sPropertyAlias];
            }
        }
    }
    return BaseAPI;
});
