/*******************************************************************************
 * Copyright (c) 2011, 2012 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 *
 ******************************************************************************/
package org.eclipse.jpt.jpa.core.jpql.spi;

import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.persistence.jpa.jpql.TypeHelper;
import org.eclipse.persistence.jpa.jpql.spi.ITypeDeclaration;
import org.eclipse.persistence.jpa.jpql.spi.ITypeRepository;

/**
 * The concrete implementation of {@link ITypeRepository} that is wrapping the design-time
 * representation of a type repository.
 *
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 3.2
 * @since 3.0
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class JpaTypeRepository implements ITypeRepository {

	/**
	 * The Java project that gives access the design-time objects representing the Java types.
	 */
	private final IJavaProject javaProject;

	/**
	 * Keeps a map of the primitives for fast access.
	 */
	private Map<String, Class<?>> primitives;

	/**
	 * The cached helper that is using this repository for retrieving {@link IJpaType types}.
	 */
	private TypeHelper typeHelper;

	/**
	 * The types that have been cached for faster access.
	 */
	private final Map<String, IJpaType> types;

	/**
	 * The {@link IJpaType} that represents a unresolvable or simply an unknown type, which is created
	 * when {@link #getType(String)} is invoked with {@link IJpaType#UNRESOLVABLE_TYPE}.
	 */
	private IJpaType unresolvableType;

	/**
	 * Creates a new <code>JpaTypeRepository</code>.
	 *
	 * @param javaProject The Java project that gives access the design-time objects representing
	 * the Java types
	 */
	public JpaTypeRepository(IJavaProject javaProject) {
		super();
		this.javaProject = javaProject;
		this.types       = new HashMap<String, IJpaType>();
	}

	protected String buildInnerTypeName(String typeName, int index) {
		StringBuilder sb = new StringBuilder();
		sb.append(typeName.substring(0, index));
		sb.append("$");
		sb.append(typeName.substring(index + 1, typeName.length()));
		return sb.toString();
	}

	protected Map<String, Class<?>> buildPrimitives() {
		Map<String, Class<?>> primitives = new HashMap<String, Class<?>>();
		primitives.put(Byte     .TYPE.getName(), Byte     .TYPE);
		primitives.put(Short    .TYPE.getName(), Short    .TYPE);
		primitives.put(Character.TYPE.getName(), Character.TYPE);
		primitives.put(Integer  .TYPE.getName(), Integer  .TYPE);
		primitives.put(Long     .TYPE.getName(), Long     .TYPE);
		primitives.put(Float    .TYPE.getName(), Float    .TYPE);
		primitives.put(Double   .TYPE.getName(), Double   .TYPE);
		primitives.put(Boolean  .TYPE.getName(), Boolean  .TYPE);
		return primitives;
	}

	protected IJpaType buildType(Class<?> javaType) {
		JavaType jpaType = new JavaType(this, javaType);
		types.put(jpaType.getName(), jpaType);
		return jpaType;
	}

	protected IJpaType buildType(IType type) {
		JpaType jpaType = new JpaType(this, type);
		types.put(jpaType.getName(), jpaType);
		return jpaType;
	}

	protected IJpaType buildType(String typeName) {
		IJpaType jpaType = new SimpleType(this, typeName);
		types.put(typeName, jpaType);
		return jpaType;
	}

	protected String convertToJavaArrayType(String typeName) {

		int index = typeName.indexOf("[]");
		int dimensionality = (typeName.length() - index) / 2;
		StringBuilder sb = new StringBuilder();

		while (dimensionality-- > 0) {
			sb.append("[");
		}

		String type = typeName.substring(0, index);
		Class<?> primitive = primitives.get(type);

		if (primitive != null) {
			if (primitive == Byte.TYPE) {
				sb.append("B");
			}
			else if (primitive == Character.TYPE) {
				sb.append("C");
			}
			else if (primitive == Short.TYPE) {
				sb.append("S");
			}
			else if (primitive == Integer.TYPE) {
				sb.append("I");
			}
			else if (primitive == Long.TYPE) {
				sb.append("L");
			}
			else if (primitive == Float.TYPE) {
				sb.append("F");
			}
			else if (primitive == Double.TYPE) {
				sb.append("D");
			}
			else if (primitive == Boolean.TYPE) {
				sb.append("Z");
			}
		}
		else {
			sb.append(type);
			sb.append(";");
		}

		return sb.toString();
	}

	protected Class<?> findPrimitive(String typeName) {
		if (primitives == null) {
			primitives = buildPrimitives();
		}
		return primitives.get(typeName);
	}

	/**
	 * Retrieves the design-time Java type for the given type name, which has to be the fully
	 * qualified type name.
	 *
	 * @param typeName The fully qualified type name
	 * @return The design-time Java type if it could be retrieved; <code>null</code> otherwise
	 */
	protected IType findType(String typeName) {
		try {
			return javaProject.findType(typeName);
		}
		catch (JavaModelException e) {
			return null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public IJpaType getEnumType(String enumTypeName) {

		// Make sure the enum type name is not empty before doing operations over it
		if (StringTools.stringIsEmpty(enumTypeName)) {
			return null;
		}

		// Get the position of the last dot so the enum constant can be removed
		int lastDotIndex = enumTypeName.lastIndexOf(".");

		if (lastDotIndex == -1) {
			return null;
		}

		// Retrieve the fully qualified enum type name
		String typeName = enumTypeName.substring(0, lastDotIndex);

		// Attempt to load the enum type
		IType type = findType(typeName);
		IJpaType jpaType;

		if (type != null) {
			jpaType = buildType(type);
		}
		else {
			jpaType = loadInnerType(typeName);
		}

		return (jpaType != null) && jpaType.isEnum() ? jpaType : null;
	}

	/**
	 * Returns the Java project, which gives access to the class path.
	 *
	 * @return The Java project, which gives access to the class path
	 */
	protected IJavaProject getJavaProject() {
		return javaProject;
	}

	/**
	 * {@inheritDoc}
	 */
	public IJpaType getType(Class<?> javaClass) {
		IJpaType type = types.get(javaClass.getName());
		if (type == null) {
			type = buildType(javaClass);
		}
		return type;
	}

	/**
	 * Retrieves the {@link IType} for the given {@link IResource}.
	 *
	 * @param resource The workspace location of the {@link IType} to retrieve
	 * @return The design-time representation of a Java type
	 */
	protected IType getType(IResource resource) {
		try {
			return (IType) javaProject.findElement((IPath) resource);
		}
		catch (Exception e) {
			return null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public IJpaType getType(String typeName) {

		if (StringTools.stringIsEmpty(typeName) ||
		    IJpaType.UNRESOLVABLE_TYPE == typeName) {

			return unresolvableType();
		}

		if (typeName.endsWith("[]")) {
			return loadArrayType(typeName);
		}

		if (typeName.charAt(0) == '[') {
			return loadJavaArrayType(typeName);
		}

		return loadTypeImp(typeName);
	}

	/**
	 * {@inheritDoc}
	 */
	public TypeHelper getTypeHelper() {
		if (typeHelper == null) {
			typeHelper = new TypeHelper(this);
		}
		return typeHelper;
	}

	protected IJpaType loadArrayType(String typeName) {

		IJpaType type = types.get(typeName);

		if (type == null) {
			try {
				// Try to see if the type is a JDK class, otherwise, just use the type name
				// since IJpaType doesn't support array types
				String javaTypeName = convertToJavaArrayType(typeName);
				type = buildType(Class.forName(javaTypeName));
			}
			catch (Exception e) {

				int index = typeName.indexOf("[]");
				int dimensionality = (typeName.length() - index) / 2;

				type = getType(typeName.substring(0, index));

				type.setTypeDeclaration(
					new JpaTypeDeclaration(type, new ITypeDeclaration[0], dimensionality)
				);
			}

			types.put(typeName, type);
		}

		return type;
	}

	protected IJpaType loadInnerType(String typeName) {

		while (true) {

			int index = typeName.lastIndexOf(".");

			if (index == -1) {
				return null;
			}

			typeName = buildInnerTypeName(typeName, index);
			IJpaType cachedType = types.get(typeName);

			if (cachedType != null) {
				return cachedType;
			}

			// Attempt to load the Java type
			IType type = findType(typeName);

			// A Java type exists, return it
			if (type != null) {
				return buildType(type);
			}
		}
	}

	protected IJpaType loadJavaArrayType(String typeName) {

		IJpaType type = types.get(typeName);

		if (type == null) {
			try {
				// Try to see if the type is a JDK class, otherwise, just use the type name
				// since IJpaType doesn't support array types
				type = buildType(Class.forName(typeName));
			}
			catch (Exception e) {

				int index = typeName.lastIndexOf("[");
				int dimensionality = index / 2;

				type = getType(typeName.substring(index, typeName.endsWith(";") ? typeName.length() - 1 : typeName.length()));

				type.setTypeDeclaration(
					new JpaTypeDeclaration(type, new ITypeDeclaration[0], dimensionality)
				);
			}

			types.put(typeName, type);
		}

		return type;
	}

	protected IJpaType loadTypeImp(String typeName) {

		IJpaType type = types.get(typeName);

		// The type was already cached, simply return it
		if (type != null) {
			return type;
		}

		// First check for primitive, they don't have a corresponding IJpaType
		Class<?> primitive = findPrimitive(typeName);

		if (primitive != null) {
			return buildType(primitive);
		}

		// Attempt to load the Java type
		IType iType = findType(typeName);

		// A Java type exists, return it
		if (iType != null) {
			return buildType(iType);
		}

		// Now try with a possible inner enum type
		type = loadInnerType(typeName);

		// No Java type exists, create a "null" IJpaType
		if (type == null) {
			type = buildType(typeName);
		}

		return type;
	}

	protected IJpaType unresolvableType() {
		if (unresolvableType == null) {
			unresolvableType = new SimpleType(this, IJpaType.UNRESOLVABLE_TYPE);
		}
		return unresolvableType;
	}
}