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

import java.util.Dictionary;
import java.util.function.BiFunction;
import java.util.function.Function;

import org.apache.felix.dm.Component;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.ServiceDependency;
import org.apache.felix.dm.lambda.ServiceDependencyBuilder;
import org.osgi.framework.ServiceReference;

public class ServiceDependencyBuilderImpl<S> extends ServiceCallbacksBuilderImpl<S, ServiceDependencyBuilder<S>> implements ServiceDependencyBuilder<S> {
    private final Class<S> m_serviceIface;
    private final Component m_component;
    private String m_filter;
    private ServiceReference<S> m_ref;
    private boolean m_required;
    private String m_debug;
    private boolean m_propagate;
    private Object m_propagateInstance;
    private String m_propagateMethod;
    private Object m_defaultImpl;
    private long m_timeout = -1;
    private boolean m_requiredSet;

    public ServiceDependencyBuilderImpl(Component component, Class<S> service) {
        super(service);
        m_serviceIface = service;
        m_component = component;
    }

    public ServiceDependencyBuilder<S> filter(String filter) {
        m_filter = filter;
        return this;
    }

    public ServiceDependencyBuilder<S> ref(ServiceReference<S> ref) {
        m_ref = ref;
        return this;
    }

    public ServiceDependencyBuilder<S> optional() {
        return required(false);
    }

    public ServiceDependencyBuilder<S> required() {
        return required(true);
    }

    public ServiceDependencyBuilder<S> required(boolean required) {
        m_required = required;
        m_requiredSet = true;
        return this;
    }

    public ServiceDependencyBuilder<S> debug(String label) {
        m_debug = label;
        return this;
    }

    public ServiceDependencyBuilder<S> propagate() {
        return propagate(true);
    }

    public ServiceDependencyBuilder<S> propagate(boolean propagate) {
        m_propagate = propagate;
        return this;
    }

    public ServiceDependencyBuilder<S> propagate(Object instance, String method) {
        m_propagateInstance = instance;
        m_propagateMethod = method;
        return this;
    }
    
    public ServiceDependencyBuilder<S> propagate(Function<ServiceReference<S>, Dictionary<String, Object>> propagate) {
        Object wrappedCallback = new Object() {
            @SuppressWarnings("unused")
            Dictionary<String, Object> propagate(ServiceReference<S> ref) {
                return propagate.apply(ref);
            }
        };
        propagate(wrappedCallback, "propagate");
        return this;
    }    

    public ServiceDependencyBuilder<S> propagate(BiFunction<ServiceReference<S>, S, Dictionary<String, Object>> propagate) {
        Object wrappedCallback = new Object() {
            @SuppressWarnings("unused")
            Dictionary<String, Object> propagate(ServiceReference<S> ref, S service) {
                return propagate.apply(ref, service);
            }
        };
        propagate(wrappedCallback, "propagate");
        return this;
    }    

    public ServiceDependencyBuilder<S> defImpl(Object defaultImpl) {
        m_defaultImpl = defaultImpl;
        return this;
    }

    public ServiceDependencyBuilder<S> timeout(long timeout) {
        m_timeout = timeout;
        required();
        return this;
    }

   	// Build final ServiceDependency object.
    @Override
    public ServiceDependency build() {
        DependencyManager dm = m_component.getDependencyManager();
        if (m_ref != null && m_filter != null) {
            throw new IllegalArgumentException("Can not set ref and filter at the same time");
        }
        if (m_serviceIface == null && (m_ref == null || m_filter == null)) {
            throw new IllegalArgumentException("service interface not specified, and no service reference or service filter specified.");
        }
        ServiceDependency sd = m_timeout > -1 ? dm.createTemporalServiceDependency(m_timeout) : dm.createServiceDependency();
        if (m_ref != null) {
            sd.setService(m_serviceIface, m_ref);
        } else {
            sd.setService(m_serviceIface, m_filter);
        }
        if (! m_requiredSet) {
            m_required = Helpers.isDependencyRequiredByDefault(m_component);
        }
        sd.setRequired(m_required);
        sd.setDefaultImplementation(m_defaultImpl);
        if (m_debug != null) {
            sd.setDebug(m_debug);
        }
        if (m_propagate) {
            sd.setPropagate(true);
        } else if (m_propagateInstance != null) {
            if (m_propagateMethod == null) {
                throw new IllegalArgumentException("propagate instance can't be null");
            }
            sd.setPropagate(m_propagateInstance, m_propagateMethod);
        }
        if (hasCallbacks()) {
            sd.setCallbacks(m_callbackInstance, m_added, m_changed, m_removed, m_swapped);
        } else if (hasRefs()) {
            Object cb = createCallbackInstance();
            sd.setCallbacks(cb, "add", "change", "remove", m_swapRefs.size() > 0 ? "swap" : null);
        }
        
        if (m_autoConfigField != null) {
            sd.setAutoConfig(m_autoConfigField);
        } else {
            sd.setAutoConfig(m_autoConfig);
        }
        
        sd.setDereference(m_dereferenceServiceInternally); // false if the callback signature only contains service ref and/or component parameters.
        return sd;
    }
    
}
