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

import static org.apache.juneau.internal.ClassUtils.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;

import org.apache.juneau.annotation.*;
import org.apache.juneau.reflect.*;

/**
 * A lookup table for resolving bean types by name.
 *
 * <p>
 * In a nutshell, provides a simple mapping of bean class objects to identifying names.
 *
 * <p>
 * Class names are defined through the {@link Bean#typeName() @Bean(typeName)} annotation.
 *
 * <p>
 * The dictionary is used by the framework in the following ways:
 * <ul>
 * 	<li>If a class type cannot be inferred through reflection during parsing, then a helper <js>"_type"</js> is added
 * 		to the serialized output using the name defined for that class in this dictionary.  This helps determine the
 * 		real class at parse time.
 * 	<li>The dictionary name is used as element names when serialized to XML.
 * </ul>
 */
public class BeanRegistry {

	private final Map<String,ClassMeta<?>> map;
	private final Map<Class<?>,String> reverseMap;
	private final BeanContext beanContext;
	private final boolean isEmpty;

	BeanRegistry(BeanContext beanContext, BeanRegistry parent, Class<?>...classes) {
		this.beanContext = beanContext;
		this.map = new ConcurrentHashMap<>();
		this.reverseMap = new ConcurrentHashMap<>();
		for (Class<?> c : beanContext.getBeanDictionaryClasses())
			addClass(c);
		if (parent != null)
			for (Map.Entry<String,ClassMeta<?>> e : parent.map.entrySet())
				addToMap(e.getKey(), e.getValue());
		for (Class<?> c : classes)
			addClass(c);
		isEmpty = map.isEmpty();
	}

	private void addClass(Class<?> c) {
		try {
			if (c != null) {
				ClassInfo ci = ClassInfo.of(c);
				if (ci.isChildOf(Collection.class)) {
					@SuppressWarnings("rawtypes")
					Collection cc = castOrCreate(Collection.class, c);
					for (Object o : cc) {
						if (o instanceof Class)
							addClass((Class<?>)o);
						else
							throw new BeanRuntimeException("Collection class ''{0}'' passed to BeanRegistry does not contain Class objects.", c.getName());
					}
				} else if (ci.isChildOf(Map.class)) {
					Map<?,?> m = castOrCreate(Map.class, c);
					for (Map.Entry<?,?> e : m.entrySet()) {
						String typeName = stringify(e.getKey());
						Object v = e.getValue();
						ClassMeta<?> val = null;
						if (v instanceof Type)
							val = beanContext.getClassMeta((Type)v);
						else if (v.getClass().isArray())
							val = getTypedClassMeta(v);
						else
							throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but value of type ''{1}'' found in map is not a Type object.", c.getName(), v.getClass().getName());
						addToMap(typeName, val);
					}
				} else {
					Bean b = c.getAnnotation(Bean.class);
					if (b == null || b.typeName().isEmpty())
						throw new BeanRuntimeException("Class ''{0}'' was passed to BeanRegistry but it doesn't have a @Bean(typeName) annotation defined.", c.getName());
					addToMap(b.typeName(), beanContext.getClassMeta(c));
				}
			}
		} catch (BeanRuntimeException e) {
			throw e;
		} catch (Exception e) {
			throw new BeanRuntimeException(e);
		}
	}

	private ClassMeta<?> getTypedClassMeta(Object array) {
		int len = Array.getLength(array);
		if (len == 0)
			throw new BeanRuntimeException("Map entry had an empty array value.");
		Type type = (Type)Array.get(array, 0);
		Type[] args = new Type[len-1];
		for (int i = 1; i < len; i++)
			args[i-1] = (Type)Array.get(array, i);
		return beanContext.getClassMeta(type, args);
	}

	private void addToMap(String typeName, ClassMeta<?> cm) {
		map.put(typeName, cm);
		reverseMap.put(cm.innerClass, typeName);
	}

	/**
	 * Gets the class metadata for the specified bean type name.
	 *
	 * @param typeName
	 * 	The bean type name as defined by {@link Bean#typeName() @Bean(typeName)}.
	 * 	Can include multi-dimensional array type names (e.g. <js>"X^^"</js>).
	 * @return The class metadata for the bean.
	 */
	public ClassMeta<?> getClassMeta(String typeName) {
		if (isEmpty)
			return null;
		if (typeName == null)
			return null;
		ClassMeta<?> cm = map.get(typeName);
		if (cm != null)
			return cm;
		if (typeName.charAt(typeName.length()-1) == '^') {
			cm = getClassMeta(typeName.substring(0, typeName.length()-1));
			if (cm != null) {
				cm = beanContext.getClassMeta(Array.newInstance(cm.innerClass, 1).getClass());
				map.put(typeName, cm);
			}
			return cm;
		}
		return null;
	}

	/**
	 * Given the specified class, return the dictionary name for it.
	 *
	 * @param c The class to lookup in this registry.
	 * @return The dictionary name for the specified class in this registry, or <jk>null</jk> if not found.
	 */
	public String getTypeName(ClassMeta<?> c) {
		if (isEmpty)
			return null;
		return reverseMap.get(c.innerClass);
	}

	/**
	 * Returns <jk>true</jk> if this dictionary has an entry for the specified type name.
	 *
	 * @param typeName The bean type name.
	 * @return <jk>true</jk> if this dictionary has an entry for the specified type name.
	 */
	public boolean hasName(String typeName) {
		return getClassMeta(typeName) != null;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append('{');
		for (Map.Entry<String,ClassMeta<?>> e : map.entrySet())
			sb.append(e.getKey()).append(":").append(e.getValue().toString(true)).append(", ");
		sb.append('}');
		return sb.toString();
	}
}
