/*-
 * ~~~~~~licensing~~~~~~
 * test-producers
 * ==========
 * 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.api;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;

import ru.entaxy.platform.base.objects.factory.EntaxyFactory;
import ru.entaxy.platform.base.support.CommonUtils;

public interface EntaxyProducerService {

    public static interface DIRECTIVES {

        String LIFECYCLE = "@LIFECYCLE";

        /*
         * usage: {"@SKIP": ['command1', 'command2-', 'command3+']}
         * where
         * 	'command1' - skip command1
         * 	'command2-' - skip ALL BEFORE command2
         * 	'command3+' - skip ALL AFTER command3
         */
        String SKIP = "@SKIP";

        /*
         * usage: {"@CONTINUE_ON_EXCEPTION": ['command1', 'command2-', 'command3+']}
         * where
         * 	'command1' - continue after exception in command1
         * 	'command2-' - continue after exception in ANY command BEFORE command2
         * 	'command3+' - continue after exception in ANY command AFTER command3
         */
        String CONTINUE_ON_EXCEPTION = "@CONTINUE_ON_EXCEPTION";

    };

    public static interface INSTRUCTIONS {

        String PRINT_OUTPUT = "printOutput";
        String SKIP = "skip";
        String CONTINUE_ON_EXCEPTION = "continueOnException";
        String MAX_COUNT = "maxCount";
        String CURRENT_ITERATION = "currentCount";

        public static interface ARTIFACT {

            public static final String VERSION = "artifact.version";
            public static final String TIMESTAMP = "artifact.timestamp";
            public static final String VERSION_POLICY = "artifact.version.policy";

        }

    };

    public ProducerResult produce(String configuration);

    public ProducerResult produce(JsonObject configuration);

    public ProducerResult produce(String configuration, String instructions);

    public ProducerResult produce(JsonObject configuration, String instructions);

    public List<EntaxyProducer> getAllProducers();

    public EntaxyProducer getProducerForType(String type);

    public EntaxyFactory findFactoryById(String factoryId);

    default public boolean isFactoryOfType(String factoryId, String type) {
        EntaxyFactory f = findFactoryById(factoryId);
        while (f != null) {
            if (f.getType().equals(type))
                return true;
            if (!CommonUtils.isValid(f.getParent()))
                return false;
            f = findFactoryById(f.getParent());
        }
        return false;

    }

    default public List<EntaxyFactory> findFactories(String filter) {
        try {
            Filter osgiFilter = FrameworkUtil.createFilter(filter);
            return findFactories(osgiFilter);
        } catch (InvalidSyntaxException e) {
            LoggerFactory.getLogger(EntaxyProducerService.class).error(String.format("Invalid filter [%s]", filter));
            return new ArrayList<>();
        }
    };

    default public List<EntaxyFactory> findFactories(Filter filter) {
        List<EntaxyFactory> allFactories = new ArrayList<>();
        for (EntaxyProducer producer : getAllProducers())
            allFactories.addAll(producer.getAllFactories());
        return EntaxyProducerUtils.filterFactories(filter, allFactories);
    };

    public List<ProducingCommandExecutor> getAvailableCommands();

    public void registerCommand(ProducingCommandExecutor commandExecutor);

    public void extendLifecycle(String lifecycle, ProducingCommandExecutor commandExecutor,
            Map<String, Object> parameters);

    public ProducingCommandExecutor getCommandById(String id);
}
