/*******************************************************************************
 * Copyright (c) 2011 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 org.eclipse.jdt.core.BindingKey;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.Signature;
import org.eclipse.persistence.jpa.jpql.spi.IConstructor;
import org.eclipse.persistence.jpa.jpql.spi.IType;
import org.eclipse.persistence.jpa.jpql.spi.ITypeDeclaration;
import org.eclipse.persistence.jpa.jpql.spi.ITypeRepository;

/**
 * The concrete implementation of {@link IConstructor} that is wrapping the {@link IMethod}
 * representation of a Java constructor (either coming from a Java compiled file or a Java source
 * file).
 *
 * 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.1
 * @since 3.0
 * @author Pascal Filion
 */
public class ClassConstructor implements IConstructor {

	/**
	 * The information of the constructor.
	 */
	private IMethod method;

	/**
	 * The declaring type of this constructor.
	 */
	private JpaType type;

	/**
	 * The cached {@link ITypeDeclaration ITypeDeclarations} representing each of the constructor's
	 * parameter types.
	 */
	private ITypeDeclaration[] typeDeclarations;

	/**
	 * Creates a new <code>ClassConstructor</code>.
	 *
	 * @param type The declaring type of this constructor
	 * @param methodInfo The information of the constructor
	 */
	public ClassConstructor(JpaType type, IMethod method) {
		super();
		this.type   = type;
		this.method = method;
	}

	protected ITypeDeclaration[] buildParameterTypes() {

		BindingKey bindingKey = new BindingKey(method.getKey());
		String signature = bindingKey.toSignature();

		int count = Signature.getParameterCount(signature);
		ITypeDeclaration[] typeDeclarations = new ITypeDeclaration[count];
		int index = 0;

		for (String parameterType : Signature.getParameterTypes(signature)) {

			// 1. Retrieve the parameter type (without the type parameters)
			String parameterTypeName = Signature.getTypeErasure(parameterType);

			// 3. Convert the type signature to a dot-based name
			parameterTypeName = Signature.toString(parameterTypeName);

			// 4. Create the ITypeDeclaration
			typeDeclarations[index++] = new JpaTypeDeclaration(
				getTypeRepository().getType(parameterTypeName),
				buildTypeParameters(parameterType),
				Signature.getArrayCount(parameterType)
			);
		}

		return typeDeclarations;
	}

	protected ITypeDeclaration[] buildTypeParameters(String signature) {

		String[] typeParameters = Signature.getTypeArguments(signature);
		ITypeDeclaration[] generics = new ITypeDeclaration[typeParameters.length];

		for (int index = 0; index < typeParameters.length; index++) {
			String typeParameter = typeParameters[index];

			// 1. Retrieve the parameter type (without the wild cards)
			switch (Signature.getTypeSignatureKind(typeParameter)) {
				case Signature.WILDCARD_TYPE_SIGNATURE: {
					typeParameter = typeParameter.substring(1);
				}
			}

			if (typeParameter.length() == 0) {
				generics[index] = getTypeRepository().getTypeHelper().objectTypeDeclaration();
			}
			else {
				String typeParameterName = Signature.getTypeErasure(typeParameter);

				// 3. Convert the type signature to a dot-based name
				typeParameterName = Signature.toString(typeParameterName);

				// 3. Retrieve the IType for the type parameter
				IType genericType = getTypeRepository().getType(typeParameterName);

				if (genericType.isResolvable()) {
					generics[index] = genericType.getTypeDeclaration();
				}
				else {
					generics[index] = getTypeRepository().getTypeHelper().objectTypeDeclaration();
				}
			}
		}

		return generics;
	}

	/**
	 * {@inheritDoc}
	 */
	public ITypeDeclaration[] getParameterTypes() {
		if (typeDeclarations == null) {
			typeDeclarations = buildParameterTypes();
		}
		return typeDeclarations;
	}

	protected ITypeRepository getTypeRepository() {
		return type.getTypeRepository();
	}
}