/*
 * 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.net.URL;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

import org.apache.felix.dm.Component;
import org.apache.felix.dm.ComponentStateListener;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.context.ComponentContext;
import org.apache.felix.dm.context.DependencyContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;

/**
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public abstract class AbstractDecorator  {
    protected volatile DependencyManager m_manager;
    private final Map<Object, Component> m_services = new ConcurrentHashMap<>();
    private volatile ComponentContext m_decoratorComponent;
    private final Map<Dependency, Dependency> m_depclones = new HashMap<>();

    public abstract Component createService(Object[] properties) throws Exception;
    
    /**
     * Catches our DependencyManager handle from our component init method.
     */
    public void init(Component c) {
        m_manager = c.getDependencyManager();
        m_decoratorComponent = (ComponentContext) c;
    }
    
    /**
     * Extra method, which may be used by sub-classes, when adaptee has changed.
     * For now, it's only used by the FactoryConfigurationAdapterImpl class, 
     * but it might also make sense to use this for Resource Adapters ...
     */
    public void updateService(Object[] properties) throws Exception {
        throw new NoSuchMethodException("Method updateService not implemented");
    }
    
    /**
     * Set some service properties to all already instantiated services.
     */
    public void setServiceProperties(Dictionary<?,?> serviceProperties) {
        for (Component component : m_services.values()) {
            component.setServiceProperties(serviceProperties);
        }
    }
    
    /**
     * Remove a StateListener from all already instantiated services.
     */
    public void addStateListener(ComponentStateListener listener) {
        for (Component component : m_services.values()) {
            component.add(listener);
        }
    }

    /**
     * Remove a StateListener from all already instantiated services.
     */
    public void removeStateListener(ComponentStateListener listener) {
        for (Component component : m_services.values()) {
            component.remove(listener);
        }
    }
    
    /**
     * Add a Dependency to all already instantiated services.
     */
    public void addDependency(Dependency ... dependencies) {
        for (Component component : m_services.values()) {
	    	Dependency[] copy = Stream.of(dependencies)
	    			.map(d -> (DependencyContext) d)
	    			.map(dc -> dc.createCopy())
	    			.toArray(Dependency[]::new);
	    	for (int i = 0; i < dependencies.length; i ++) {
	    		m_depclones.put(dependencies[i], copy[i]);
	    	}
            component.add(copy);
        }
    }
    
    /**
     * Remove a Dependency from all instantiated services.
     */
    public void removeDependency(Dependency d) {
        for (Component component : m_services.values()) {
        	Dependency copy = m_depclones.remove(d);
        	if (copy != null) {
        		component.remove(copy);
        	}
        }
    }
    
    // callbacks for FactoryConfigurationAdapterImpl from the ConfigAdmin thread
    @SuppressWarnings("rawtypes")
    public void updated(String pid, Dictionary properties) throws ConfigurationException {
        // FELIX-5193: invoke the updated callback in the internal decorator component queue, in order
        // to safely detect if the component is still active or not.
        InvocationUtil.invokeUpdated(m_decoratorComponent.getExecutor(), () -> updatedSafe(pid, properties));
    }
    
    @SuppressWarnings("rawtypes")
    private void updatedSafe(String pid, Dictionary properties) throws Exception {
        if (!m_decoratorComponent.isActive()) {
            // Our decorator component has been removed: ignore the configuration update.
            return;
        }
        Component service = m_services.get(pid);
        if (service == null) {
            service = createService(new Object[] { properties });
            m_services.put(pid, service);
            m_manager.add(service);
        } else {
            updateService(new Object[] { properties, service });
        }
    }

    public void deleted(String pid) {
        Component service = m_services.remove(pid);
        if (service != null) {
            m_manager.remove(service);
        }
    }

    // callbacks for resources
    public void added(URL resource) throws Exception {
        Component newService = createService(new Object[] { resource });
        m_services.put(resource, newService);
        m_manager.add(newService);
    }

    public void removed(URL resource) {
        Component newService = m_services.remove(resource);
        if (newService == null) {
            throw new IllegalStateException("Service should not be null here.");
        }
        m_manager.remove(newService);
    }
    
    // callbacks for services
    public void added(ServiceReference<?> ref, Object service) throws Exception {
        Component newService = createService(new Object[] { ref, service });
        m_services.put(ref, newService);
        m_manager.add(newService);
    }
    
    public void removed(ServiceReference<?> ref, Object service) {
        Component newService;
        newService = (Component) m_services.remove(ref);
        if (newService == null) {
            throw new IllegalStateException("Service should not be null here.");
        }
        m_manager.remove(newService);
    }
    
    public void swapped(ServiceReference<?> oldRef, Object oldService, ServiceReference<?> newRef, Object newService) {
        Component service = (Component) m_services.remove(oldRef);
        if (service == null) {
            throw new IllegalStateException("Service should not be null here.");
        }           
        m_services.put(newRef, service);
    }
    
    // callbacks for bundles
    public void added(Bundle bundle) throws Exception {
        Component newService = createService(new Object[] { bundle });
        m_services.put(bundle, newService);
        m_manager.add(newService);
    }
    
    public void removed(Bundle bundle) {
        Component newService;
        newService = (Component) m_services.remove(bundle);
        if (newService == null) {
            throw new IllegalStateException("Service should not be null here.");
        }
        m_manager.remove(newService);
    }
      
    public void stop() {
        for (Component component : m_services.values()) {
            m_manager.remove(component);
        }
        m_services.clear();
    }    
    
    public void configureAutoConfigState(Component target, ComponentContext source) {
        configureAutoConfigState(target, source, BundleContext.class);
        configureAutoConfigState(target, source, ServiceRegistration.class);
        configureAutoConfigState(target, source, DependencyManager.class);
        configureAutoConfigState(target, source, Component.class);
    }
    
    public Map<Object, Component> getServices() {
        return m_services;
    }

    private void configureAutoConfigState(Component target, ComponentContext source, Class<?> clazz) {
        String name = source.getAutoConfigInstance(clazz);
        if (name != null) {
            target.setAutoConfig(clazz, name);
        }
        else {
            target.setAutoConfig(clazz, source.getAutoConfig(clazz));
        }
    }    
}
