/**
 * @file configUtils.js
 *
 * Permission is hereby granted to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to use it for personal 
 * or non-commercial purposes, with the following restrictions:
 *
 * 1. **No Copying or Redistribution**: The Software or any of its parts may not 
 *    be copied, merged, distributed, sublicensed, or sold without explicit 
 *    prior written permission from the author.
 * 
 * 2. **Commercial Use**: Any use of the Software for commercial purposes requires 
 *    a valid license, obtainable only with the explicit consent of the author.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, 
 * OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 * SOFTWARE.
 *
 * Ownership of this code remains solely with the original author. Unauthorized 
 * use of this Software is strictly prohibited.
 *
 * @summary Utility for managing and validating configuration values.
 * @description Utility for managing and validating configuration values.
 * @module ConfigUtils
 * @requires ValidationUtils
 * @requires Logger
 * @exports ConfigUtils
 * @version 0.1.0
 * @since 0.1.0
 */


const ValidationUtils = require("./validationUtils");
const Logger = require("./logger");

class ConfigUtils {
    constructor(defaultConfig, IloggerEnabled , IloggerLevel) {
        const loggerEnabled = IloggerEnabled || true;
        const loggerLevel = IloggerLevel || "warn";
        this.logger = new Logger(loggerEnabled, loggerLevel, 'ConfigUtils');
        this.defaultConfig = defaultConfig;
        this.validationUtils = new ValidationUtils(loggerEnabled, loggerLevel);
    }

    // Initialize configuration
    initConfig(config) {
        this.logger.info("Initializing configuration...");

        // Validate the provided configuration
        const validatedConfig = this.validationUtils.validateSchema(config, this.defaultConfig, this.defaultConfig.functionality.softwareType.default);

        this.logger.info("Configuration initialized successfully.");

        return validatedConfig;
    }


    // Update configuration
    updateConfig(currentConfig, newConfig) {
        this.logger.info("Updating configuration...");

        // Merge 2 configs and validate the result
        const mergedConfig = this.mergeObjects(currentConfig, newConfig);
        
        // Merge current configuration with new values
        const updatedConfig = this.validationUtils.validateSchema(mergedConfig, this.defaultConfig, this.defaultConfig.functionality.softwareType.default);

        this.logger.info("Configuration updated successfully.");
        return updatedConfig;
    }

    // loop through objects and merge them obj1 will be updated with obj2 values
    mergeObjects(obj1, obj2) {
        for (let key in obj2) {
            if (obj2.hasOwnProperty(key)) {
                if (typeof obj2[key] === 'object') {
                    if (!obj1[key]) {
                        obj1[key] = {};
                    }
                    this.mergeObjects(obj1[key], obj2[key]);
                } else {
                    obj1[key] = obj2[key];
                }
            }
        }
        return obj1;
    }
}

module.exports = ConfigUtils;
