/*******************************************************************************
 * Copyright (c) 2005, 2014 IBM Corporation and others.
 * 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:
 *     Andrew Niefer (IBM) - Initial API and implementation
 *     Bryan Wilkinson (QNX)
 *     Markus Schorn (Wind River Systems)
 *     Thomas Corbat (IFS)
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.core.runtime.Assert;

/**
 * Specialization of a class.
 */
public class CPPClassSpecialization extends CPPSpecialization
		implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost {

	public static class RecursionResolvingBinding extends ProblemBinding implements ICPPMember, IRecursionResolvingBinding {
		public static RecursionResolvingBinding createFor(IBinding original, IASTNode point) {
			if (original instanceof ICPPMethod)
				return new RecursionResolvingMethod(point, original.getNameCharArray());
			if (original instanceof ICPPField)
				return new RecursionResolvingField(point, original.getNameCharArray());
			return new RecursionResolvingBinding(point, original.getNameCharArray());
		}

		private RecursionResolvingBinding(IASTNode node, char[] arg) {
			super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg);
			Assert.isTrue(CPPASTNameBase.sAllowRecursionBindings, getMessage());
		}

		@Override
		public int getVisibility() {
			return ICPPASTVisibilityLabel.v_public;
		}

		@Override
		public ICPPClassType getClassOwner() {
			return null;
		}
	}

	public final static class RecursionResolvingField extends RecursionResolvingBinding implements ICPPField {
		public RecursionResolvingField(IASTNode node, char[] arg) {
			super(node, arg);
		}

		@Override
		public ICompositeType getCompositeTypeOwner() {
			return null;
		}
	}

	public final static class RecursionResolvingMethod extends RecursionResolvingBinding implements ICPPMethod {
		public RecursionResolvingMethod(IASTNode node, char[] arg) {
			super(node, arg);
		}

		@Override
		public ICPPParameter[] getParameters() {
			return ICPPParameter.EMPTY_CPPPARAMETER_ARRAY;
		}

		@Override
		public int getRequiredArgumentCount() {
			return 0;
		}

		@Override
		public IScope getFunctionScope() {
			return null;
		}

		@Override
		public boolean isNoReturn() {
			return false;
		}

		@Override
		public boolean isDestructor() {
			return false;
		}

		@Override
		public ICPPFunctionType getType() {
			return new ProblemFunctionType(getID());
		}

		@Override
		public boolean isOverride() {
			return false;
		}

		@Override
		public boolean isFinal() {
			return false;
		}

		@Override
		public boolean isConstexpr() {
			return false;
		}
	}

	private ICPPClassSpecializationScope specScope;
	private ObjectMap specializationMap= ObjectMap.EMPTY_MAP;
	private ICPPBase[] bases;
	private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>() {
		@Override
		protected Set<IBinding> initialValue() {
			return new HashSet<>();
		}
	};

	public CPPClassSpecialization(ICPPClassType specialized, IBinding owner,
			ICPPTemplateParameterMap argumentMap) {
		super(specialized, owner, argumentMap);
	}

	@Override
	public ICPPClassType getSpecializedBinding() {
		return (ICPPClassType) super.getSpecializedBinding();
	}

	@Override
	public IBinding specializeMember(IBinding original) {
		return specializeMember(original, null);
	}

	@Override
	public IBinding specializeMember(IBinding original, IASTNode point) {
		synchronized (this) {
			IBinding result= (IBinding) specializationMap.get(original);
			if (result != null)
				return result;
		}

		IBinding result;
		Set<IBinding> recursionProtectionSet= fInProgress.get();
		if (!recursionProtectionSet.add(original))
			return RecursionResolvingBinding.createFor(original, point);

		try {
			result= CPPTemplates.createSpecialization(this, original, point);
		} finally {
			recursionProtectionSet.remove(original);
		}

		synchronized (this) {
			IBinding concurrent= (IBinding) specializationMap.get(original);
			if (concurrent != null)
				return concurrent;
			if (specializationMap == ObjectMap.EMPTY_MAP)
				specializationMap = new ObjectMap(2);
			specializationMap.put(original, result);
			return result;
		}
	}

	@Override
	public void checkForDefinition() {
		// Ambiguity resolution ensures that declarations and definitions are resolved.
	}

	@Override
	public ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier() {
		IASTNode definition= getDefinition();
		if (definition != null) {
			IASTNode node= definition;
			while (node instanceof IASTName)
				node= node.getParent();
			if (node instanceof ICPPASTCompositeTypeSpecifier)
				return (ICPPASTCompositeTypeSpecifier) node;
		}
		return null;
	}

	@Override
	public ICPPBase[] getBases() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getBases(null);
	}

	@Override
	public ICPPBase[] getBases(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null) {
			if (bases == null) {
				bases = ClassTypeHelper.getBases(this);
			}
			return bases;
		}

		return scope.getBases(point);
	}

	@Override
	public ICPPField[] getDeclaredFields() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getDeclaredFields(null);
	}

	@Override
	public ICPPField[] getDeclaredFields(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null)
			return ClassTypeHelper.getDeclaredFields(this);

		return scope.getDeclaredFields(point);
	}

	@Override
	public ICPPMethod[] getDeclaredMethods() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getDeclaredMethods(null);
	}

	@Override
	public ICPPMethod[] getDeclaredMethods(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null)
			return ClassTypeHelper.getDeclaredMethods(this);

		return scope.getDeclaredMethods(point);
	}

	@Override
	public ICPPConstructor[] getConstructors() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getConstructors(null);
	}

	@Override
	public ICPPConstructor[] getConstructors(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null)
			return ClassTypeHelper.getConstructors(this);

		return scope.getConstructors(point);
	}

	@Override
	public IBinding[] getFriends() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getFriends(null);
	}

	@Override
	public IBinding[] getFriends(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null)
			return ClassTypeHelper.getFriends(this);

		return scope.getFriends(point);
	}

	@Override
	public ICPPClassType[] getNestedClasses() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getNestedClasses(null);
	}

	@Override
	public ICPPClassType[] getNestedClasses(IASTNode point) {
		ICPPClassSpecializationScope scope= getSpecializationScope();
		if (scope == null)
			return ClassTypeHelper.getNestedClasses(this);

		return scope.getNestedClasses(point);
	}

	@Override
	public IField[] getFields() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getFields(null);
	}

	@Override
	public IField[] getFields(IASTNode point) {
		return ClassTypeHelper.getFields(this, point);
	}

	@Override
	public IField findField(String name) {
		return ClassTypeHelper.findField(this, name);
	}

	@Override
	public ICPPMethod[] getMethods() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getMethods(null);
	}

	@Override
	public ICPPMethod[] getMethods(IASTNode point) {
		return ClassTypeHelper.getMethods(this, point);
	}

	@Override
	public ICPPMethod[] getAllDeclaredMethods() {
		CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
		return getAllDeclaredMethods(null);
	}

	@Override
	public ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
		return ClassTypeHelper.getAllDeclaredMethods(this, point);
	}

	@Override
	public int getKey() {
		if (getDefinition() != null)
			return getCompositeTypeSpecifier().getKey();

		return getSpecializedBinding().getKey();
	}

	@Override
	public ICPPClassScope getCompositeScope() {
		final ICPPClassScope specScope= getSpecializationScope();
		if (specScope != null)
			return specScope;

		final ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier();
		if (typeSpecifier != null)
			return typeSpecifier.getScope();

		return null;
	}

	protected ICPPClassSpecializationScope getSpecializationScope() {
		checkForDefinition();
		if (getDefinition() != null)
			return null;

		// Implicit specialization: must specialize bindings in scope.
		if (specScope == null) {
			specScope = new CPPClassSpecializationScope(this);
		}
		return specScope;
	}

	@Override
	public boolean isSameType(IType type) {
		if (type == this)
			return true;
		if (type instanceof ITypedef)
			return type.isSameType(this);

		if (type instanceof ICPPClassSpecialization) {
			return isSameClassSpecialization(this, (ICPPClassSpecialization) type);
		}
		return false;
	}

	@Override
	public Object clone() {
		return this;
	}

	@Override
	public boolean isAnonymous() {
		if (getNameCharArray().length > 0)
			return false;

		ICPPASTCompositeTypeSpecifier spec= getCompositeTypeSpecifier();
		if (spec == null) {
			return getSpecializedBinding().isAnonymous();
		}

		IASTNode node= spec.getParent();
		if (node instanceof IASTSimpleDeclaration) {
			if (((IASTSimpleDeclaration) node).getDeclarators().length == 0) {
				return true;
			}
		}
		return false;
	}

	public static boolean isSameClassSpecialization(ICPPClassSpecialization t1, ICPPClassSpecialization t2) {
		// Exclude class template specialization or class instance.
		if (t2 instanceof ICPPTemplateInstance || t2 instanceof ICPPTemplateDefinition ||
				t2 instanceof IProblemBinding) {
			return false;
		}

		if (t1.getKey() != t2.getKey())
			return false;

		if (!CharArrayUtils.equals(t1.getNameCharArray(), t2.getNameCharArray()))
			return false;

		// The argument map is not significant for comparing specializations, the map is
		// determined by the owner of the specialization. This is different for instances,
		// which have a separate implementation for isSameType().
		final IBinding owner1= t1.getOwner();
		final IBinding owner2= t2.getOwner();

		// For a specialization that is not an instance the owner has to be a class-type.
		if (!(owner1 instanceof ICPPClassType) || !(owner2 instanceof ICPPClassType))
			return false;

		return ((ICPPClassType) owner1).isSameType((ICPPClassType) owner2);
	}

	@Override
	public boolean isFinal() {
		ICPPASTCompositeTypeSpecifier typeSpecifier = getCompositeTypeSpecifier();
		if (typeSpecifier != null) {
			return typeSpecifier.isFinal();
		}
		return false;
	}

	@Override
	public int getVisibility(IBinding member) {
		return ClassTypeHelper.getVisibility(this, member);
	}
}
