package net.brutex.xservices.util;

import lombok.Data;
import lombok.Singular;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.configuration2.Configuration;
import org.apache.commons.configuration2.FileBasedConfiguration;
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
import org.apache.commons.configuration2.builder.PropertiesBuilderParametersImpl;
import org.apache.commons.configuration2.event.ConfigurationEvent;
import org.apache.commons.configuration2.event.EventListener;
import org.apache.commons.configuration2.ex.ConfigurationException;

import jakarta.servlet.ServletContext;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
 * A configuration object for the MiscService -> Eventmanager. Implemented as singleton.
 * @author Brian Rosenberger, bru@brutex.de
**/
@Data
@Slf4j
public class EventmanagerConfiguration {

    public static final String KEY = "net.brutex.xservices.EventmanagerConfiguration";

    private static class InstanceHolder {
        public static final EventmanagerConfiguration instance = new EventmanagerConfiguration();
    }

    private EventmanagerConfiguration() {
         refreshConfig();
    }

    public static EventmanagerConfiguration getInstance() {
        return InstanceHolder.instance;
    }


    private String targeturl;
    private int interval;
    private String jdbc_memdb;
    private String jdbc_filedb;
    private boolean isEmitterActive = true;
    private int cleaner_interval;
    private List<ALFEventFilter> alf_filter = new ArrayList<>();
    private int init_delay;
    private long logMaxAge;


    public synchronized EventmanagerConfiguration refreshConfig() {
        log.trace("Reading EventmanagerConfiguration from file eventmanager.properties.");
        FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
                new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class)
                        .configure(new PropertiesBuilderParametersImpl().setFileName("../eventmanager.properties"));

        try {
            Configuration config = builder.getConfiguration();

            /* Read from eventmanager.properties file */
            this.targeturl = config.getString("target.url");
            this.interval = config.getInt("interval", 10);
            this.jdbc_memdb = config.getString("memdb", "jdbc:h2:mem:lockdb;DB_CLOSE_DELAY=-1;");
            this.jdbc_filedb = config.getString("fdb", "jdbc:h2:mem:lockdb;DB_CLOSE_DELAY=-1;");
            this.isEmitterActive = config.getBoolean("emitter_active", true);
            this.cleaner_interval = config.getInt("cleaner_interval", 5);
            this.logMaxAge = config.getLong("logMaxAge", 72);
            List<String> lst = config.getList(String.class,"alf_filter", new ArrayList<String>());

            for ( String c :lst ) {
                try{
                    alf_filter.add( (ALFEventFilter) Class.forName(c).getDeclaredConstructor().newInstance());
                } catch (ClassNotFoundException e) {
                    log.error("Cannot find class for alf filter with name '{}'.", c);
                } catch (InvocationTargetException | InstantiationException | IllegalAccessException |
                         NoSuchMethodException e) {
                    log.error("Cannot instantiate class for alf filter with name '{}'.", c);
                }
            }
            this.init_delay = config.getInt("init_delay", 15);


        } catch (ConfigurationException e) {
            log.error("Error loading configuration for event manager in XServices MiscServices: {}", e.getMessage());
            throw new RuntimeException(e);
        }
        return this;
    }


}
