/*
 * 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.felix.dm.impl;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;

import org.apache.felix.dm.Component;
import org.apache.felix.dm.ComponentDeclaration;
import org.apache.felix.dm.ComponentExecutorFactory;
import org.apache.felix.dm.context.ComponentContext;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentFactory;

/**
 * The Dependency Manager delegates all components addition/removal to this class.
 * If a ComponentExecutorFactory is registered in the OSGi registry, this class will use it to get an 
 * Executor used for components management and lifecycle callbacks.
 * 
 * @see {@link ComponentFactory}
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class ComponentScheduler {
    private final static ComponentScheduler m_instance = new ComponentScheduler();
    private final static String PARALLEL = "org.apache.felix.dependencymanager.parallel";
    private volatile ComponentExecutorFactory m_componentExecutorFactory;
    private final Executor m_serial = new SerialExecutor(null);
    private ConcurrentMap<Component, Component> m_pending = new ConcurrentHashMap<>();

    public static ComponentScheduler instance() {
        return m_instance;
    }

    protected void bind(final ComponentExecutorFactory componentExecutorFactory) {
        m_componentExecutorFactory = componentExecutorFactory;
        m_serial.execute(new Runnable() {
            @Override
            public void run() {
                for (Component c : m_pending.keySet()) {
                    createComponentExecutor(m_componentExecutorFactory, c);
                    ((ComponentContext) c).start();
                }
                m_pending.clear();
            }
        });
    }

    protected void unbind(ComponentExecutorFactory threadPool) {
        m_componentExecutorFactory = null;
    }

    public void add(final Component c) {
        if (mayStartNow(c)) {
            ((ComponentContext) c).start();
        }
        else {
            // The component requires a threadpool: delay execution until one is available.
            m_serial.execute(new Runnable() {
                @Override
                public void run() {
                    ComponentExecutorFactory execFactory = m_componentExecutorFactory;
                    if (execFactory == null) {
                        m_pending.put(c, c);
                    }
                    else {
                        createComponentExecutor(execFactory, c);
                        ((ComponentContext) c).start();
                    }
                }
            });
        }
    }

    public void remove(final Component c) {
        m_pending.remove(c);
        ((ComponentContext) c).stop();
    }

    private boolean mayStartNow(Component c) {
        ComponentExecutorFactory execFactory = m_componentExecutorFactory;
        BundleContext ctx = c.getDependencyManager().getBundleContext();
        String parallel = ctx.getProperty(PARALLEL);

        if (execFactory == null) {
            // No ComponentExecutorFactory available. If a "parallel" OSGi system property is specified, 
            // we have to wait for a ComponentExecutorFactory servoce if the component class name is matching one of the 
            // prefixes specified in the "parallel" system property.
            if (parallel != null && requiresThreadPool(c, parallel)) {
                return false; // wait for a threadpool
            } else {
                return true; // no threadpool required, start the component now, synchronously
            }
        }
        else {
            // A threadpool is there. If the "parallel" OSGi system property is not specified, we can start the component
            // now and we'll use the threadpool for it.
            // But if the "parallel" system property is specified, the component will use the threadpool only if it's
            // classname is starting with one of the prefixes specified in the property.
            if (parallel == null || requiresThreadPool(c, parallel)) {
		createComponentExecutor(execFactory, c);
            }
            return true; // start the component now, possibly using the threadpool (see above).
        }
    }

    private boolean requiresThreadPool(Component c, String parallel) {
        // The component declared from our DM Activator can not be parallel.
        ComponentDeclaration decl = c.getComponentDeclaration();
        if (ComponentScheduler.class.getName().equals(decl.getName())) {
            return false;
        }

        for (String prefix : parallel.trim().split(",")) {
            prefix = prefix.trim();
            boolean not = prefix.startsWith("!");
            if (not) {
                prefix = prefix.substring(1).trim();
            }
            if ("*".equals(prefix) || c.getComponentDeclaration().getClassName().startsWith(prefix)) {
                return !not;
            }
        }
        return false;
    }
    
    private void createComponentExecutor(ComponentExecutorFactory execFactory, Component c) {
        Executor exec = execFactory.getExecutorFor(c);
        if (exec != null) {
            ((ComponentContext) c).setThreadPool(exec);
        }
    }
}
