/*
 * 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.aries.blueprint.container;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.concurrent.Callable;

import org.apache.aries.blueprint.ExtendedBlueprintContainer;
import org.apache.aries.blueprint.ExtendedServiceReferenceMetadata;
import org.apache.aries.blueprint.di.Recipe;
import org.apache.aries.blueprint.di.CollectionRecipe;
import org.osgi.framework.ServiceReference;
import org.osgi.service.blueprint.container.BlueprintEvent;
import org.osgi.service.blueprint.container.ReifiedType;
import org.osgi.service.blueprint.container.ComponentDefinitionException;
import org.osgi.service.blueprint.container.ServiceUnavailableException;
import org.osgi.service.blueprint.reflect.ReferenceMetadata;
import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A recipe to create an unary OSGi service reference.
 *
 * TODO: check synchronization / thread safety
 *
 * TODO: looks there is a potential problem if the service is unregistered between a call
 *        to ServiceDispatcher#loadObject() and when the actual invocation finish
 *
 * @version $Rev: 950985 $, $Date: 2010-06-03 14:19:22 +0100 (Thu, 03 Jun 2010) $
 */
public class ReferenceRecipe extends AbstractServiceReferenceRecipe {

    private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceRecipe.class);

    private final ReferenceMetadata metadata;
    private Object proxy;

    private volatile ServiceReference trackedServiceReference;
    private volatile Object trackedService;
    private final Object monitor = new Object();

    public ReferenceRecipe(String name,
                           ExtendedBlueprintContainer blueprintContainer,
                           ReferenceMetadata metadata,
                           CollectionRecipe listenersRecipe,
                           List<Recipe> explicitDependencies) {
        super(name, blueprintContainer, metadata, listenersRecipe, explicitDependencies);
        this.metadata = metadata;
    }

    @Override
    protected Object internalCreate() throws ComponentDefinitionException {
        try {
            if (explicitDependencies != null) {
                for (Recipe recipe : explicitDependencies) {
                    recipe.create();
                }
            }
            // Create the proxy
            Set<Class> interfaces = new HashSet<Class>();
            if (this.metadata.getInterface() != null) {
                interfaces.add(loadClass(this.metadata.getInterface()));
            }
            if (this.metadata instanceof ExtendedServiceReferenceMetadata && ((ExtendedServiceReferenceMetadata) this.metadata).getRuntimeInterface() != null) {
                interfaces.add(((ExtendedServiceReferenceMetadata) this.metadata).getRuntimeInterface());
            }

            proxy = createProxy(new ServiceDispatcher(), interfaces);

            // Add partially created proxy to the context
            ServiceProxyWrapper wrapper = new ServiceProxyWrapper();

            addPartialObject(wrapper);

            // Handle initial references
            createListeners();
            updateListeners();            

            // Return a ServiceProxy that can injection of references or proxies can be done correctly
            return wrapper;
        } catch (ComponentDefinitionException e) {
            throw e;
        } catch (Throwable t) {
            throw new ComponentDefinitionException(t);
        }
    }

    protected void doStop() {
        synchronized (monitor) {
            unbind();
            monitor.notifyAll();
        }
    }

    protected void retrack() {
        ServiceReference ref = getBestServiceReference();
        if (ref != null) {
            bind(ref);
        } else {
            unbind();
        }
    }

    protected void track(ServiceReference ref) {
        // TODO: make this behavior configurable through a custom attribute
        // TODO:      policy = sticky | replace
        synchronized (monitor) {
            if (trackedServiceReference == null) {
                retrack();
            }
        }
    }

    protected void untrack(ServiceReference ref) {
        // TODO: make this behavior configurable through a custom attribute
        // TODO:      policy = sticky | replace
        synchronized (monitor) {
            if (trackedServiceReference == ref) {
                retrack();
            }
        }
    }

    private void bind(ServiceReference ref) {
        LOGGER.debug("Binding reference {} to {}", getName(), ref);
        synchronized (monitor) {
            if (trackedServiceReference != null) {
                blueprintContainer.getBundleContext().ungetService(trackedServiceReference);
            }
            trackedServiceReference = ref;
            trackedService = null;
            monitor.notifyAll();
            bind(trackedServiceReference, proxy);
        }
    }

    private void unbind() {
        LOGGER.debug("Unbinding reference {}", getName());
        synchronized (monitor) {
            if (trackedServiceReference != null) {
                unbind(trackedServiceReference, proxy);
                blueprintContainer.getBundleContext().ungetService(trackedServiceReference);
                trackedServiceReference = null;
                trackedService = null;
                monitor.notifyAll();
            }
        }
    }

    private Object getService() throws InterruptedException {
        synchronized (monitor) {
            if (isStarted() && trackedServiceReference == null && metadata.getTimeout() > 0
                    && metadata.getAvailability() == ServiceReferenceMetadata.AVAILABILITY_MANDATORY) {
                blueprintContainer.getEventDispatcher().blueprintEvent(new BlueprintEvent(BlueprintEvent.WAITING, blueprintContainer.getBundleContext().getBundle(), blueprintContainer.getExtenderBundle(), new String[] { getOsgiFilter() }));
                monitor.wait(metadata.getTimeout());
            }
            if (trackedServiceReference == null) {
                if (isStarted()) {
                    LOGGER.info("Timeout expired when waiting for OSGi service {}", getOsgiFilter());
                    throw new ServiceUnavailableException("Timeout expired when waiting for OSGi service", getOsgiFilter());
                } else {
                    throw new ServiceUnavailableException("The Blueprint container is being or has been destroyed", getOsgiFilter());
                }
            }
            if (trackedService == null) {
                trackedService = blueprintContainer.getService(trackedServiceReference);
            }
            if (trackedService == null) {
                throw new IllegalStateException("getService() returned null for " + trackedServiceReference);
            }
            return trackedService;
        }
    }

    private ServiceReference getServiceReference() throws InterruptedException {
        synchronized (monitor) {
            if (!optional) {
                getService();
            }
            return trackedServiceReference;
        }
    }

    public class ServiceDispatcher implements Callable<Object> {

        public Object call() throws Exception {
            return getService();
        }

    }

    public class ServiceProxyWrapper implements AggregateConverter.Convertible {

        public Object convert(ReifiedType type) throws Exception {
            if (type.getRawClass() == ServiceReference.class) {
                return getServiceReference();
            } else if (type.getRawClass().isInstance(proxy)) {
                return proxy;
            } else {
                throw new ComponentDefinitionException("Unable to convert to " + type);
            }
        }

    }

}
