/*******************************************************************************
 * Copyright (c) 2009, 2012 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.core.internal.resource.java.binary;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.resource.java.Annotation;
import org.eclipse.jpt.common.core.resource.java.JavaResourceMember;
import org.eclipse.jpt.common.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;

/**
 * binary persistent member
 */
abstract class BinaryMember
	extends BinaryAnnotatedElement
	implements JavaResourceMember
{

	private boolean final_;  // 'final' is a reserved word
	private boolean transient_;  // 'transient' is a reserved word
	private boolean public_;  // 'public' is a reserved word
	private boolean static_;  // 'static' is a reserved word
	boolean protected_; // 'protected' is a reserved word


	// ********** construction/initialization **********

	public BinaryMember(JavaResourceNode parent, Adapter adapter) {
		super(parent, adapter);
		this.final_ = this.buildFinal();
		this.transient_ = this.buildTransient();
		this.public_ = this.buildPublic();
		this.static_ = this.buildStatic();
		this.protected_ = this.buildProtected();
	}


	// ********** updating **********

	@Override
	public void update() {
		super.update();
		this.setFinal(this.buildFinal());
		this.setTransient(this.buildTransient());
		this.setPublic(this.buildPublic());
		this.setStatic(this.buildStatic());
		this.setProtected(this.buildProtected());
	}


	// ********** simple state **********

	// ***** final
	public boolean isFinal() {
		return this.final_;
	}

	private void setFinal(boolean final_) {
		boolean old = this.final_;
		this.final_ = final_;
		this.firePropertyChanged(FINAL_PROPERTY, old, final_);
	}

	private boolean buildFinal() {
		try {
			return Flags.isFinal(this.getMember().getFlags());
		} catch (JavaModelException ex) {
			JptCommonCorePlugin.log(ex);
			return false;
		}
	}

	// ***** transient
	public boolean isTransient() {
		return this.transient_;
	}

	private void setTransient(boolean transient_) {
		boolean old = this.transient_;
		this.transient_ = transient_;
		this.firePropertyChanged(TRANSIENT_PROPERTY, old, transient_);
	}

	private boolean buildTransient() {
		try {
			return Flags.isTransient(this.getMember().getFlags());
		} catch (JavaModelException ex) {
			JptCommonCorePlugin.log(ex);
			return false;
		}
	}

	// ***** public
	public boolean isPublic() {
		return this.public_;
	}

	private void setPublic(boolean public_) {
		boolean old = this.public_;
		this.public_ = public_;
		this.firePropertyChanged(PUBLIC_PROPERTY, old, public_);
	}

	private boolean buildPublic() {
		try {
			return Flags.isPublic(this.getMember().getFlags());
		} catch (JavaModelException ex) {
			JptCommonCorePlugin.log(ex);
			return false;
		}
	}

	// ***** static
	public boolean isStatic() {
		return this.static_;
	}

	private void setStatic(boolean static_) {
		boolean old = this.static_;
		this.static_ = static_;
		this.firePropertyChanged(STATIC_PROPERTY, old, static_);
	}

	private boolean buildStatic() {
		try {
			return Flags.isStatic(this.getMember().getFlags());
		} catch (JavaModelException ex) {
			JptCommonCorePlugin.log(ex);
			return false;
		}
	}

	// ***** protected
	public boolean isProtected() {
		return this.protected_;
	}

	private void setProtected(boolean protected_) {
		boolean old = this.protected_;
		this.protected_ = protected_;
		this.firePropertyChanged(PROTECTED_PROPERTY, old, protected_);
	}

	private boolean buildProtected() {
		try {
			return Flags.isProtected(this.getMember().getFlags());
		} catch (JavaModelException ex) {
			JptCommonCorePlugin.log(ex);
			return false;
		}
	}

	// ********** miscellaneous **********

	IMember getMember() {
		return this.getAdapter().getElement();
	}

	private Adapter getAdapter() {
		return (Adapter) this.adapter;
	}

	/**
	 * Strip off the type signature's parameters if present.
	 * Convert to a readable string.
	 */
	static String convertTypeSignatureToTypeName(String typeSignature) {
		return convertTypeSignatureToTypeName(typeSignature, EmptyIterable.<ITypeParameter>instance());
	}
	
	/**
	 * Strip off the type signature's parameters if present.
	 * Convert to a readable string.
	 */
	static String convertTypeSignatureToTypeName(String typeSignature, Iterable<ITypeParameter> typeParameters) {
		return (typeSignature == null) ? null : convertTypeSignatureToTypeName_(typeSignature, typeParameters);
	}
	
	/**
	 * no null check
	 */
	static String convertTypeSignatureToTypeName_(String typeSignature) {
		return convertTypeSignatureToTypeName(typeSignature, EmptyIterable.<ITypeParameter>instance());
	}
	
	/**
	 * no null check
	 */
	static String convertTypeSignatureToTypeName_(String typeSignature, Iterable<ITypeParameter> typeParameters) {
		String erasureSignature = Signature.getTypeErasure(typeSignature);
		if (Signature.getTypeSignatureKind(erasureSignature) == Signature.TYPE_VARIABLE_SIGNATURE) {
			try {
				String typeParameterName = Signature.toString(erasureSignature);
				for (ITypeParameter typeParameter : typeParameters) {
					if (typeParameterName.equals(typeParameter.getElementName())) {
						String[] bounds = (typeParameter == null) ? new String[0] : typeParameter.getBoundsSignatures();
						if (bounds.length > 0) {
							return convertTypeSignatureToTypeName_(bounds[0], typeParameters);
						}
					}
				}
			}
			catch (JavaModelException jme) {
				JptCommonCorePlugin.log(jme);
			}
		}
		else if (Signature.getTypeSignatureKind(erasureSignature) == Signature.ARRAY_TYPE_SIGNATURE) {
			int dim = Signature.getArrayCount(erasureSignature);
			String arrayTypeName = convertTypeSignatureToTypeName(Signature.getElementType(erasureSignature), typeParameters);
			return Signature.toString(Signature.createArraySignature(Signature.createTypeSignature(arrayTypeName, true), dim));
		}
		else if (Signature.getTypeSignatureKind(erasureSignature) == Signature.WILDCARD_TYPE_SIGNATURE) {
			// if signature is ? (wildcard) or ? super X (bottom bounded), return top bound, which is Object
			if (String.valueOf(Signature.C_STAR).equals(erasureSignature) || erasureSignature.startsWith(String.valueOf(Signature.C_SUPER))) {
				return "java.lang.Object";
			}
			// else return top bound
			else {
				return Signature.toString(erasureSignature.substring(1));
			}
		}
		return Signature.toString(erasureSignature);
	}
	
	static boolean convertTypeSignatureToTypeIsArray(String typeSignature) {
		return (typeSignature == null) ? false : Signature.getTypeSignatureKind(typeSignature) == Signature.ARRAY_TYPE_SIGNATURE;
	}
	
	static int convertTypeSignatureToTypeArrayDimensionality(String typeSignature) {
		return (typeSignature == null) ? 0 : Signature.getArrayCount(typeSignature);
	}
	
	static String convertTypeSignatureToTypeArrayComponentTypeName(String typeSignature, Iterable<ITypeParameter> typeParameters) {
		return (typeSignature == null) ? null : convertTypeSignatureToTypeName(Signature.getElementType(typeSignature), typeParameters);
	}
	
	/**
	 * these types can be arrays (e.g. "java.lang.String[]");
	 * but they won't have any further nested generic type arguments
	 * (e.g. "java.util.Collection<java.lang.String>")
	 */
	static List<String> convertTypeSignatureToTypeTypeArgumentNames(String typeSignature, Iterable<ITypeParameter> typeParameters) {
		if (typeSignature == null) {
			return Collections.emptyList();
		}
		
		String[] typeArgumentSignatures = Signature.getTypeArguments(typeSignature);
		if (typeArgumentSignatures.length == 0) {
			return Collections.emptyList();
		}
		
		ArrayList<String> names = new ArrayList<String>(typeArgumentSignatures.length);
		for (String typeArgumentSignature : typeArgumentSignatures) {
			names.add(convertTypeSignatureToTypeName(typeArgumentSignature, typeParameters));
		}
		return names;
	}
	
	public boolean isPublicOrProtected() {
		return isPublic() || isProtected();
	}
	
	// ********** IMember adapter **********

	interface Adapter extends BinaryAnnotatedElement.Adapter {
		/**
		 * Return the adapter's JDT member (IType, IField, IMethod).
		 */
		IMember getElement();
		
		Iterable<ITypeParameter> getTypeParameters();
	}


	// ********** unsupported JavaResourceMember implementation **********

	public Annotation setPrimaryAnnotation(String primaryAnnotationName, Iterable<String> supportingAnnotationNames) {
		throw new UnsupportedOperationException();
	}

	public void resolveTypes(CompilationUnit astRoot) {
		throw new UnsupportedOperationException();
	}

	public boolean isFor(String memberName, int occurrence) {
		throw new UnsupportedOperationException();
	}
}
