package org.yamcs;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Used to create processors as defined in yprocessor.yaml
 *
 * @author mache
 *
 */
public class ProcessorFactory {
    private static Logger log = LoggerFactory.getLogger(ProcessorFactory.class.getName());

    /**
     * Returns the processor types as defined in <tt>processor.yaml</tt>
     */
    public static List<String> getProcessorTypes() {
        if (!YConfiguration.isDefined("processor")) {
            return Collections.emptyList();
        }
        YConfiguration conf = YConfiguration.getConfiguration("processor");
        return new ArrayList<>(conf.getKeys());
    }

    /**
     * Create a processor with the give name, type, creator and spec
     *
     * type is used to load the tm, parameter and command classes as defined in processor.yaml spec if not null is
     * passed as an extra argument to those classes - it is used for example when creating replay processors to pass on
     * the data that has to be replayed. should probably be changed from string to some sort of object.
     *
     * @param yamcsInstance
     * @param name
     * @param type
     * @param creator
     * @param spec
     * @return a new processor
     * @throws ProcessorException
     * @throws ConfigurationException
     */
    public static Processor create(String yamcsInstance, String name, String type, String creator, Object spec)
            throws ProcessorException, ConfigurationException {
        YConfiguration processorConfig = null;
        YConfiguration conf = YConfiguration.getConfiguration("processor");

        List<ServiceWithConfig> serviceList = new ArrayList<>();
        try {
            if (!conf.containsKey(type)) {
                throw new ConfigurationException("No processor type '" + type + "' found in " + conf.getPath());
            }
            conf = conf.getConfig(type);
            
            if (conf.containsKey("services")) {
                serviceList = YamcsServer.createServices(yamcsInstance, conf.getServiceConfigList("services"));
            } else {
                log.warn("Deprecated configuration in {}. Please use services", conf.getPath());
                if (conf.containsKey(type, "telemetryProvider")) {
                    Map<String, Object> m = (Map<String, Object>) conf.getSubMap(type, "telemetryProvider");
                    String tmClass = YConfiguration.getString(m, "class");
                    Object tmArgs = m.get("args");
                    serviceList.add(YamcsServer.createService(yamcsInstance, tmClass, tmClass, tmArgs));
                }

                if (conf.containsKey("parameterProviders")) {
                    serviceList.addAll(
                            YamcsServer.createServices(yamcsInstance, conf.getServiceConfigList("parameterProviders")));
                }
                if (conf.containsKey(type, "commandReleaser")) {
                    Map<String, Object> m = (Map<String, Object>) conf.getSubMap(type, "commandReleaser");
                    String commandClass = YConfiguration.getString(m, "class");
                    Object commandArgs = m.get("args");
                    serviceList.add(YamcsServer.createService(yamcsInstance, commandClass, commandClass, commandArgs));
                }
            }
            if (conf.containsKey("config")) {
                processorConfig = conf.getConfig("config");
            }
        } catch (IOException e) {
            throw new ConfigurationException("Cannot load service", e);
        }
        return create(yamcsInstance, name, type, serviceList, creator, processorConfig, spec);
    }

    /**
     * Create a Processor by specifying the service.
     * 
     * The type is not used in this case, except for showing it in the yamcs monitor.
     * 
     * @param instance
     * @param name
     * @param type
     * @param creator
     * @param config
     * @return
     * @throws ProcessorException
     * @throws ConfigurationException
     **/
    public static Processor create(String instance, String name, String type, List<ServiceWithConfig> serviceList,
            String creator, YConfiguration config, Object spec) throws ProcessorException, ConfigurationException {
        Processor proc = new Processor(instance, name, type, creator);

        proc.init(serviceList, config, spec);
        return proc;
    }

    /**
     * creates a processor with the services already instantiated. used from unit tests
     */
    public static Processor create(String yamcsInstance, String name, ProcessorService... services)
            throws ProcessorException, ConfigurationException {
        List<ServiceWithConfig> serviceList = new ArrayList<>();
        for (ProcessorService service : services) {
            serviceList.add(
                    new ServiceWithConfig(service, service.getClass().getName(), service.getClass().getName(), null));
        }
        return create(yamcsInstance, name, "test", serviceList, "test", null, null);
    }
}

@@ -125,88 +125,8 @@
 ist;
-%0Aimport java.util.Map;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0A/*
@@ -170,17 +170,16 @@
 ined in 
-y
 processo
@@ -247,99 +247,8 @@
 ry %7B
-%0A    private static Logger log = LoggerFactory.getLogger(ProcessorFactory.class.getName());
 %0A%0A  
@@ -1617,36 +1617,16 @@
 viceList
- = new ArrayList%3C%3E()
 ;%0A      
@@ -1860,73 +1860,8 @@
     
-%0A            if (conf.containsKey(%22services%22)) %7B%0A                
 serv
@@ -1956,1252 +1956,8 @@
 ));%0A
-            %7D else %7B%0A                log.warn(%22Deprecated configuration in %7B%7D. Please use services%22, conf.getPath());%0A                if (conf.containsKey(type, %22telemetryProvider%22)) %7B%0A                    Map%3CString, Object%3E m = (Map%3CString, Object%3E) conf.getSubMap(type, %22telemetryProvider%22);%0A                    String tmClass = YConfiguration.getString(m, %22class%22);%0A                    Object tmArgs = m.get(%22args%22);%0A                    serviceList.add(YamcsServer.createService(yamcsInstance, tmClass, tmClass, tmArgs));%0A                %7D%0A%0A                if (conf.containsKey(%22parameterProviders%22)) %7B%0A                    serviceList.addAll(%0A                            YamcsServer.createServices(yamcsInstance, conf.getServiceConfigList(%22parameterProviders%22)));%0A                %7D%0A                if (conf.containsKey(type, %22commandReleaser%22)) %7B%0A                    Map%3CString, Object%3E m = (Map%3CString, Object%3E) conf.getSubMap(type, %22commandReleaser%22);%0A                    String commandClass = YConfiguration.getString(m, %22class%22);%0A                    Object commandArgs = m.get(%22args%22);%0A                    serviceList.add(YamcsServer.createService(yamcsInstance, commandClass, commandClass, commandArgs));%0A                %7D%0A            %7D
 %0A   

Remove deprecated parsing of processor.yaml