/*
 * 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;

import java.util.Collection;
import java.util.Dictionary;
import java.util.Map;

import org.osgi.annotation.versioning.ProviderType;

/**
 * Configuration dependency that can track the availability of a (valid) configuration. To use
 * it, specify a PID for the configuration. The dependency is required by default. If you define
 * an optional configuration dependency, the updated callback will be invoked with an empty Dictionary,
 * or with a type-safe configuration (which in this case can provide some default methods that you can
 * use to inialize your component).
 * <p>
 * Also, only managed services are supported, not factories. If you need support for factories, then
 * you can use 
 * {@link DependencyManager#createFactoryConfigurationAdapterService(String, String, boolean)}.
 * There are a couple of things you need to be aware of when implementing the 
 * <code>updated(Dictionary)</code> method:<p>
 * <ul>
 * <li>Make sure it throws a <code>ConfigurationException</code> or any other exception when you 
 * get a configuration that is invalid. In this case, the dependency will not change: 
 * if it was not available, it will still not be. If it was available, it will remain available 
 * and implicitly assume you keep working with your old configuration.</li>
 * <li>This method will be called before all required dependencies are available. Make sure you
 * do not depend on these to parse your settings.</li>
 * <li>When the configuration is lost, updated callback is invoked with a null dictionary parameter,
 * and then the component stop lifecycle callback is invoked.
 * <li>When the DM component is stopped, then updated(null) is not invoked.
 * </ul>
 * 
 * <p> The callback invoked when a configuration dependency is updated can supports the following signatures:<p>
 * <ul>
 * <li>callback(Dictionary) 
 * <li>callback(Component, Dictionary) 
 * <li>callback(Component, Configuration ... configTypes) // type safe configuration interface(s)
 * <li>callback(Configuration ... configTypes) // type safe configuration interface(s)
 * <li>callback(Dictionary, Configuration ... configTypes) // type safe configuration interfaces(s)
 * <li>callback(Component, Dictionary, Configuration ... configTypes) // type safe configuration interfaces(s)
 * </ul>
 * 
 * <p> Support for a custom Configuration type is a new feature that allows you to specify an interface that is implemented 
 * by DM and such interface is then injected to your callback instead of the actual Dictionary.
 * Using such configuration interface provides a way for creating type-safe configurations from a actual {@link Dictionary} that is
 * normally injected by Dependency Manager.
 * The callback accepts in argument an interface that you have to provide, and DM will inject a proxy that converts
 * method calls from your configuration-type to lookups in the actual map or dictionary. The results of these lookups are then
 * converted to the expected return type of the invoked configuration method.<br>
 * As proxies are injected, no implementations of the desired configuration-type are necessary!
 * </p>
 * <p>
 * The lookups performed are based on the name of the method called on the configuration type. The method names are
 * "mangled" to the following form: <tt>[lower case letter] [any valid character]*</tt>. Method names starting with
 * <tt>get</tt> or <tt>is</tt> (JavaBean convention) are stripped from these prefixes. For example: given a dictionary
 * with the key <tt>"foo"</tt> can be accessed from a configuration-type using the following method names:
 * <tt>foo()</tt>, <tt>getFoo()</tt> and <tt>isFoo()</tt>.<p> 
 * 
 * If the property contains a dot (which is invalid in java method names), then dots (".") can be converted using the following conventions: 
 * <ul>
 * 
 * <li> if the method name follows the javabean convention and/or kamel casing convention, then each capital letter is assumed to map to a "dot", 
 * followed by the same letter in lower case. This means only lower case properties are 
 * supported in this case. Example: getFooBar() or fooBar() will map to "foo.bar" property.
 * 
 * <li> else, if the method name follows the standard OSGi metatype specification, then dots  
 * are encoded as "_"; and "_" is encoded as "__". (see OSGi r6 compendium, chapter 105.9.2).
 * Example: "foo_BAR()" is mapped to "foo.BAR" property; "foo__BAR_zoo()" is mapped to "foo_BAR.zoo" property.
 * </ul>
 * <p>
 * The return values supported are: primitive types (or their object wrappers), strings, enums, arrays of
 * primitives/strings, {@link Collection} types, {@link Map} types, {@link Class}es and interfaces. When an interface is
 * returned, it is treated equally to a configuration type, that is, it is returned as a proxy.
 * </p>
 * <p>
 * Arrays can be represented either as comma-separated values, optionally enclosed in square brackets. For example:
 * <tt>[ a, b, c ]</tt> and <tt>a, b,c</tt> are both considered an array of length 3 with the values "a", "b" and "c".
 * Alternatively, you can append the array index to the key in the dictionary to obtain the same: a dictionary with
 * "arr.0" =&gt; "a", "arr.1" =&gt; "b", "arr.2" =&gt; "c" would result in the same array as the earlier examples.
 * </p>
 * <p>
 * Maps can be represented as single string values similarly as arrays, each value consisting of both the key and value
 * separated by a dot. Optionally, the value can be enclosed in curly brackets. Similar to array, you can use the same
 * dot notation using the keys. For example, a dictionary with 
 * 
 * <pre>{@code "map" => "{key1.value1, key2.value2}"}</pre> 
 * 
 * and a dictionary with <p>
 * 
 * <pre>{@code "map.key1" => "value1", "map2.key2" => "value2"}</pre> 
 * 
 * result in the same map being returned.
 * Instead of a map, you could also define an interface with the methods <tt>getKey1()</tt> and <tt>getKey2</tt> and use
 * that interface as return type instead of a {@link Map}.
 * <p>
 * In case a lookup does not yield a value from the underlying map or dictionary, the following rules are applied:
 * <ol>
 * <li>primitive types yield their default value, as defined by the Java Specification;
 * <li>string, {@link Class}es and enum values yield <code>null</code>;
 * <li>for arrays, collections and maps, an empty array/collection/map is returned;
 * <li>for other interface types that are treated as configuration type a null-object is returned.
 * </ol>
 * <p>
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
@ProviderType
public interface ConfigurationDependency extends Dependency, ComponentDependencyDeclaration {
    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code>.
     * By default, if this method is not called, the callback name is "updated".
     * 
     * <p> The callback is invoked on the instantiated component.
     * 
     * @param callback the name of the callback method
     */
	ConfigurationDependency setCallback(String callback);

    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code>.
     * 
     * <p> the callback is invoked on the callback instance, and the component is not 
     * yet instantiated at the time the callback is invoked.
     * 
     * @param instance the object to invoke the callback on
     * @param callback the name of the callback method
     */
    ConfigurationDependency setCallback(Object instance, String callback);

    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code>.
     * 
     * <p> the callback is invoked on the callback instance, and if <code>needsInstance</code> is true, 
     * the component is instantiated at the time the callback is invoked 
     * 
     * @param instance the object to invoke the callback on.
     * @param callback the name of the callback method
     * @param needsInstance true if the component must be instantiated before the callback is invoked on the callback instance.
     */
    ConfigurationDependency setCallback(Object instance, String callback, boolean needsInstance);

    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code> with the difference that 
     * instead of a Dictionary it accepts an interface of the given configuration type.<br>
     * By default, the pid is assumed to match the fqdn of the configuration type.
     * 
     * <p>The callback is invoked on the instantiated component.
     * 
     * @param callback the name of the callback method
     * @param configType the configuration type that the callback method accepts.
     */
    ConfigurationDependency setCallback(String callback, Class<?> configType);

    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code> with the difference that 
     * instead of a Dictionary it accepts an interface of the given configuration type.<br>
     * 
     * <p> The callback is invoked on the callback instance, and at this point the component is not yet instantiated.
     * 
     * @param instance the object to invoke the callback on.
     * @param callback the name of the callback method
     * @param configType the configuration type that the callback method accepts.
     */
    ConfigurationDependency setCallback(Object instance, String callback, Class<?> configType);

    /**
     * Sets the name of the callback method that should be invoked when a configuration
     * is available. The contract for this method is identical to that of
     * <code>ManagedService.updated(Dictionary) throws ConfigurationException</code> with the difference that 
     * instead of a Dictionary it accepts an interface of the given configuration type.<br>
     * 
     * <p> the callback is invoked on the callback instance, and if <code>needsInstance</code> is true, 
     * the component is instantiated at the time the callback is invoked 
     * 
     * @param instance the object to invoke the callback on.
     * @param callback the name of the callback method
     * @param configType the configuration type that the callback method accepts.
     * @param needsInstance true if the component must be instantiated before the callback is invoked on the callback instance.
     */
    ConfigurationDependency setCallback(Object instance, String callback, Class<?> configType, boolean needsInstance);

    /**
     * Sets the <code>service.pid</code> of the configuration you are depending on.
     */
	ConfigurationDependency setPid(String pid);

    /**
     * Sets propagation of the configuration properties to the service
     * properties. Any additional service properties specified directly are
     * merged with these. Configuration properties are not propagated by default.
     * When configuration is propagated, component service properties won't be overriden by configuration properties having the same name,
     * unless you invoke <code>setPropagate(true, false)</code> method.
     * @param propagate true if configuration properties should be propagated to the component service properties. Configuration 
     * starting with a dot won't be propagated (because such property is considered as private, see Configuration Admin spec).
     * @see #setPropagate(boolean, boolean)
     */
	ConfigurationDependency setPropagate(boolean propagate);

    /**
     * Sets propagation of the configuration properties to the service
     * properties. Any additional service properties specified directly are
     * merged with these. Configuration properties are not propagated by default.
     * @param propagate true if the configuration properties must be propagated to the component service properties. Configuration 
     * starting with a dot won't be propagated (because such property is considered as private, see Configuration Admin spec).
     * @param overrideServiceProperties true if propagated configuration properties should override the component service properties 
     * having the same property name
     */
	ConfigurationDependency setPropagate(boolean propagate, boolean overrideServiceProperties);

	/**
     * The label used to display the tab name (or section) where the properties
     * are displayed. Example: "Printer Service".
     * @return The label used to display the tab name where the properties are
     *         displayed (may be localized)
     */
	ConfigurationDependency setHeading(String heading);

    /**
     * A human readable description of the PID this configuration is associated
     * with. Example: "Configuration for the PrinterService bundle".
     * 
     * @return A human readable description of the PID this configuration is
     *         associated with (may be localized)
     */
	ConfigurationDependency setDescription(String description);

    /**
     * Points to the basename of the Properties file that can localize the Meta
     * Type informations. The default localization base name for the properties
     * is OSGI-INF/l10n/bundle, but can be overridden by the manifest
     * Bundle-Localization header (see core specification, in section
     * Localization on page 68). You can specify a specific localization
     * basename file using this method (e.g.
     * <code>setLocalization("person")</code> will match person_du_NL.properties
     * in the root bundle directory.
     */
	ConfigurationDependency setLocalization(String path);

    /**
     * Adds a MetaData regarding a given configuration property.
     */
	ConfigurationDependency add(PropertyMetaData properties);
		
    /**
     * Sets the required flag which determines if this configuration dependency is required or not.
     * A configuration dependency is required by default.
     * 
     * @param required the required flag
     * @return this service dependency
     */
	ConfigurationDependency setRequired(boolean required);
	
	/**
	 * Specifies if the component instance should be instantiated when this dependency is started.
	 * The component is always instantiated when a Configuration dependency is defined, except
	 * if you set a callback instance or if you invoke this method with <code>false</code>
	 */
	ConfigurationDependency needsInstance(boolean needsInstance);
	
    /**
     * Sets the configuration property type(s) that are passed to the updated callback parameters
     * 
     * @param configType the configuration type(s) that the callback method accepts.
     */
    ConfigurationDependency setConfigType(Class<?> ... configType);
}
