/*-
 * ~~~~~~licensing~~~~~~
 * object-producing-config-support
 * ==========
 * Copyright (C) 2020 - 2025 EmDev LLC
 * ==========
 * You may not use this file except in accordance with the License Terms of the Copyright
 * Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
 * rights to the Software and any copies are the property of the Copyright Holder. Unless
 * it is explicitly allowed the Copyright Holder, the User is prohibited from using the
 * Software for commercial purposes to provide services to third parties.
 * 
 * The Copyright Holder hereby declares that the Software is provided on an "AS IS".
 * Under no circumstances does the Copyright Holder guarantee or promise that the
 * Software provided by him will be suitable or not suitable for the specific purposes
 * of the User, that the Software will meet all commercial and personal subjective
 * expectations of the User, that the Software will work properly, without technical
 * errors, quickly and uninterruptedly.
 * 
 * Under no circumstances shall the Copyright Holder or its Affiliates is not liable
 * to the User for any direct or indirect losses of the User, his expenses or actual
 * damage, including, downtime; loss of bussines; lost profit; lost earnings; loss
 * or damage to data, property, etc.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.core.producer.config;

import java.util.HashMap;
import java.util.Map;

import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.entaxy.esb.platform.runtime.base.connecting.generator.Generated;
import ru.entaxy.platform.base.objects.EntaxyObject;
import ru.entaxy.platform.base.objects.factory.EntaxyFactoryException;
import ru.entaxy.platform.config.runtime.ObjectConfig;
import ru.entaxy.platform.config.runtime.ObjectConfig.FactoryOutputConfiguration;
import ru.entaxy.platform.core.producer.api.EntaxyWrappedFactory;
import ru.entaxy.platform.core.producer.wrapper.AbstractFactoryWrapper.GenerationProcessor;

@Component(service = GenerationProcessor.class, property = {
    "generation.plugin.id=config-support", "generation.factory.type=entaxy.runtime.*",
    "generation.factory.type=!entaxy.runtime.config"
}, immediate = true)
public class ConfigProcessor implements GenerationProcessor {

    private static final Logger log = LoggerFactory.getLogger(ConfigProcessor.class);

    @Override
    public void preGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
            Map<String, Object> parameters) throws EntaxyFactoryException {

        if (!parameters.containsKey(EntaxyObject.FIELDS.PROPERTIES))
            return;

        @SuppressWarnings("unchecked")
        Map<String, Object> properties = (Map<String, Object>) parameters.get(EntaxyObject.FIELDS.PROPERTIES);

        if (!properties.containsKey(ObjectConfig.CONFIG_FIELD_NAME))
            return;
/*		
		OutputInfo oi = wrappedFactory.getOutputByType(outputType);
		if (oi == null)
			oi = wrappedFactory.getDefaultOutput();
		
		Map<String, Object> outputConfig = oi.getConfig();
		
		boolean isConfigurable = false;
		try {
			isConfigurable = (Boolean)outputConfig.get(ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME);
		} catch (Exception e) {
			log.trace("Parameter [{}] not found in [{}]:[{}]"
					, ObjectConfig.CONFIGURABLE_ATTRIBUTE_NAME
					, wrappedFactory.getId()
					, outputType);
		}
		if (!isConfigurable)
			return;
		
		boolean fieldsConfigurableByDefault = false;
		try {
			fieldsConfigurableByDefault = (Boolean)outputConfig.get(ObjectConfig.DEFAULT_FIELDS_CONFIGURABLE_ATTRIBUTE_NAME);
		} catch (Exception e) {
			log.trace("Parameter [{}] not found in [{}]:[{}]"
					, ObjectConfig.DEFAULT_FIELDS_CONFIGURABLE_ATTRIBUTE_NAME
					, wrappedFactory.getId()
					, outputType);
		}
		
		List<ObjectConfig.ConfigurableFieldsConfiguration> fieldsConfiguration = new ArrayList<>();
		
		Object configuration = outputConfig.get(ObjectConfig.CONFIGURABLE_FIELDS_ATTRIBUTE_NAME);
		if (configuration != null) {
			if (configuration instanceof List) {
				List configList = (List)configuration;
				for (Object configItem: configList) {
					if (configItem instanceof Map) {
						ObjectConfig.ConfigurableFieldsConfiguration cnf = 
								ObjectConfig.ConfigurableFieldsConfiguration.read((Map)configItem);
						fieldsConfiguration.add(cnf);
					}
				}
			} else 
			if (configuration instanceof Map) {
				ObjectConfig.ConfigurableFieldsConfiguration cnf = 
						ObjectConfig.ConfigurableFieldsConfiguration.read((Map)configuration);
				fieldsConfiguration.add(cnf);
			}
		} else {
			fieldsConfiguration.add(new ObjectConfig.ConfigurableFieldsConfiguration());
		}
*/
        FactoryOutputConfiguration conf = FactoryOutputConfiguration.read(wrappedFactory, outputType);
        if (!conf.isConfigurable)
            return;

        ObjectConfig.backupProperties(parameters);

        String objectId = parameters.get(EntaxyObject.FIELDS.OBJECT_ID).toString();

        Map<String, Object> rawValues = new HashMap<>();

        for (Map.Entry<String, Object> entry : properties.entrySet()) {

            if (entry.getKey().startsWith("#"))
                continue;

            if (!ObjectConfig.isConfigurable(wrappedFactory, outputType, entry.getKey(), conf.defaultFieldsConfigurable,
                    conf.configurations))
                continue;

            rawValues.put(entry.getKey(), entry.getValue());

            properties.put(entry.getKey(),
                    ObjectConfig.getConfigurationPrefix(objectId, objectType) + entry.getKey() + "}");

        }

        properties.put("rawValues", rawValues);

        ObjectConfig.removeConfigData(parameters);

        log.debug("preGenerate for {}:{}", wrappedFactory.getId(), wrappedFactory.getType());
    }

    @Override
    public void postGenerate(EntaxyWrappedFactory wrappedFactory, String outputType, String scope, String objectType,
            Map<String, Object> parameters, Generated generated) throws EntaxyFactoryException {
        log.debug("postGenerate for {}:{}", wrappedFactory.getFactoryId(), wrappedFactory.getFactoryType());
        // restore initial properties
        ObjectConfig.restoreBackupProperties(parameters);
    }

}
