package aQute.bnd.annotation.metatype;

import java.lang.annotation.*;

/**
 * The Metadata interface provides access to the properties that underly a
 * Configurable interface. Any Configurable interface can implement this
 * interface. The interface provides the annotations that can be used to create
 * metatype objects.
 * 
 * @ConsumerInterface
 */

public interface Meta {
	enum Type {
		Boolean,
		Byte,
		Character,
		Short,
		Integer,
		Long,
		Float,
		Double,
		String,
		Password
	}

	/**
	 * Constant NULL for default usage
	 */
	final String	NULL	= "§NULL§";

	/**
	 * The OCD Annotation maps to the OCD element in the Metatype specification.
	 * The only difference is that it is possible to create a Designate element
	 * as well.
	 * 
	 */
	@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface OCD {
		/**
		 * The name for this component. The default name is a the short class
		 * name that us un-camel cased to make it more readable.
		 * 
		 * @return The name of this component
		 */
		String name() default NULL;

		/**
		 * The id of the component. Default the name of the class in FQN
		 * notation but with nested classes using the $ as separator (not .).
		 * 
		 * The Felix webconsole always uses this id as the PID and not the pid
		 * in the Designate element. Reported as an error.
		 * 
		 * @return the id
		 */
		String id() default NULL;

		/**
		 * The localization prefix. The default localization prefix is the name
		 * of the class with a $ separator for nested classes.
		 * 
		 * @return the localization prefix.
		 */
		String localization() default NULL;

		/**
		 * A description for this ocd. The default is empty.
		 * 
		 * @return the description
		 */
		String description() default NULL;

		/**
		 * Defines if this is for a factory or not.
		 */
		boolean factory() default false;
	}

	/**
	 * The AD element in the Metatype specification.
	 * 
	 */
	@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface AD {
		/**
		 * A description of the attribute. Default is empty.
		 * 
		 * @return The description of the attribute.
		 */
		String description() default NULL;

		/**
		 * The name of the attribute. By default the un-camel cased version of
		 * the method name.
		 * 
		 * @return the name
		 */
		String name() default NULL;

		/**
		 * The id of the attribute. By default the name of the method. The id is
		 * the key used to access the properties. This is the reason the AD is a
		 * runtime annotation so the runtime can find the proper key.
		 * 
		 * @return the id
		 */
		String id() default NULL;

		/**
		 * The type of the field. This must be one of the basic types in the
		 * metatype specification. By default, the type is derived from the
		 * return type of the method. This includes most collections and arrays.
		 * Unrecognized types are defaulted to String.
		 * 
		 * @return the type to be used.
		 */
		Type type() default Type.String;

		/**
		 * The cardinality of the attribute. If not explicitly set it will be
		 * derived from the attributes return type. Collections return
		 * Integer.MIN_VALUE and arrays use Integer.MAX_VALUE.
		 * 
		 * If a single string needs to be converted to a Collection or array
		 * then the | will be used as a separator to split the line.
		 * 
		 * @return the cardinality of the attribute
		 */
		int cardinality() default 0;

		/**
		 * The minimum value. This string must be converted to the attribute
		 * type before comparison takes place.
		 * 
		 * @return the min value
		 */
		String min() default NULL;

		/**
		 * The maximum value. This string must be converted to the attribute
		 * type before comparison takes place.
		 * 
		 * @return the max value
		 */
		String max() default NULL;

		/**
		 * The default value. This value must be converted to the return type of
		 * the attribute. For multi valued returns use the | as separator.
		 * 
		 * @return the default value
		 */
		String deflt() default NULL;

		/**
		 * Indicates that this attribute is required. By default attributes are
		 * required.
		 * 
		 * @return
		 */
		boolean required() default true;

		/**
		 * Provide labels for options. These labels must match the values. If no
		 * labels are set, the un-cameled version of the values are used (if
		 * they are set of course).
		 * 
		 * @return the option labels
		 */
		String[] optionLabels() default NULL;

		/**
		 * The values of options. If not set and the return type is an enum
		 * class then the values will be derived from this return type.
		 * 
		 * @return the option labels
		 */
		String[] optionValues() default NULL;
	}
}
