/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.sling.distribution.agent.impl;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.management.ObjectName;

import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.distribution.agent.spi.DistributionAgent;
import org.apache.sling.distribution.component.impl.DistributionComponentConstants;
import org.apache.sling.distribution.component.impl.DistributionComponentKind;
import org.apache.sling.distribution.component.impl.SettingsUtils;
import org.apache.sling.distribution.log.impl.DefaultDistributionLog;
import org.apache.sling.distribution.resources.impl.OsgiUtils;
import org.apache.sling.distribution.trigger.DistributionTrigger;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An abstract OSGi service factory for registering {@link org.apache.sling.distribution.agent.impl.SimpleDistributionAgent}s
 */
abstract class AbstractDistributionAgentFactory<DistributionAgentMBeanType> {
    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final String NAME = DistributionComponentConstants.PN_NAME;

    private static final String ENABLED = "enabled";

    static final String DEFAULT_TRIGGER_TARGET = "(name=)";

    private static final String TRIGGERS_TARGET = "triggers.target";

    static final String LOG_LEVEL = "log.level";

    private final Class<DistributionAgentMBeanType> distributionAgentMBeanType;

    private ServiceRegistration componentReg;
    private ServiceRegistration mbeanServiceRegistration;
    private String agentName;
    private final List<DistributionTrigger> triggers = new CopyOnWriteArrayList<DistributionTrigger>();
    private boolean triggersEnabled = false;

    private SimpleDistributionAgent agent;

    AbstractDistributionAgentFactory(Class<DistributionAgentMBeanType> distributionAgentMBeanType) {
        this.distributionAgentMBeanType = distributionAgentMBeanType;
    }

    void activate(BundleContext context, Map<String, Object> config) {
        log.info("activating with config {}", OsgiUtils.osgiPropertyMapToString(config));

        // inject configuration
        Dictionary<String, Object> props = new Hashtable<String, Object>();

        boolean enabled = PropertiesUtil.toBoolean(config.get(ENABLED), true);
        String triggersTarget = SettingsUtils.removeEmptyEntry(PropertiesUtil.toString(config.get(TRIGGERS_TARGET), null));
        triggersEnabled = triggersTarget != null && triggersTarget.trim().length() > 0;
        agentName = PropertiesUtil.toString(config.get(NAME), null);


        if (enabled && agentName != null) {

            for (Map.Entry<String, Object> entry : config.entrySet()) {
                // skip service and component related properties
                if (entry.getKey().startsWith("service.") || entry.getKey().startsWith("component.")) {
                    continue;
                }

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

            }

            if (componentReg == null) {

                DefaultDistributionLog distributionLog = null;
                try {

                    String logLevel = PropertiesUtil.toString(config.get(LOG_LEVEL), DefaultDistributionLog.LogLevel.INFO.name());
                    DefaultDistributionLog.LogLevel level = DefaultDistributionLog.LogLevel.valueOf(logLevel.trim().toUpperCase());
                    if (level == null) {
                        level = DefaultDistributionLog.LogLevel.INFO;
                    }


                    distributionLog = new DefaultDistributionLog(DistributionComponentKind.AGENT, agentName, SimpleDistributionAgent.class, level);

                    agent = createAgent(agentName, context, config, distributionLog);
                } catch (Throwable t) {
                    if (distributionLog != null) {
                        distributionLog.error("Cannot create agent", t);
                    }
                    log.error("Cannot create agent {}", OsgiUtils.osgiPropertyMapToString(config), t);
                }


                if (agent != null) {

                    // register agent service
                    componentReg = context.registerService(DistributionAgent.class.getName(), agent, props);
                    agent.enable();


                    if (triggersEnabled) {
                        for (DistributionTrigger trigger : triggers) {
                            agent.enableTrigger(trigger);
                        }
                    }

                    Dictionary<String, String> mbeanProps = new Hashtable<String, String>();
                    mbeanProps.put("jmx.objectname", "org.apache.sling.distribution:type=agent,id=" + ObjectName.quote(agentName));

                    DistributionAgentMBeanType mbean = createMBeanAgent(agent, config);
                    mbeanServiceRegistration = context.registerService(distributionAgentMBeanType.getName(), mbean, mbeanProps);

                }

                log.info("activated agent {}", agentName);

            }
        }
    }

    synchronized void bindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) {
        triggers.add(distributionTrigger);
        if (agent != null && triggersEnabled) {
            agent.enableTrigger(distributionTrigger);
        }

    }

    synchronized void unbindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) {
        triggers.remove(distributionTrigger);

        if (agent != null) {
            agent.disableTrigger(distributionTrigger);
        }
    }


    void deactivate(BundleContext context) {
        if (componentReg != null) {
            ServiceReference reference = componentReg.getReference();
            Object service = context.getService(reference);
            if (service instanceof SimpleDistributionAgent) {
                SimpleDistributionAgent agent = (SimpleDistributionAgent) service;
                for (DistributionTrigger trigger : triggers) {
                    agent.disableTrigger(trigger);
                }
                triggers.clear();
                triggersEnabled = false;
                agent.disable();
            }

            if (safeUnregister(componentReg)) {
                componentReg = null;
            }
            agent = null;
        }

        if (safeUnregister(mbeanServiceRegistration)) {
            mbeanServiceRegistration = null;
        }

        log.info("deactivated agent {}", agentName);
    }

    private static boolean safeUnregister(ServiceRegistration serviceRegistration) {
        if (serviceRegistration != null) {
            serviceRegistration.unregister();
            return true;
        }
        return false;
    }

    protected abstract SimpleDistributionAgent createAgent(String agentName, BundleContext context, Map<String, Object> config, DefaultDistributionLog distributionLog);

    protected abstract DistributionAgentMBeanType createMBeanAgent(DistributionAgent agent, Map<String, Object> osgiConfiguration);

}
