/*******************************************************************************
 * Copyright (c) 2011, 2013 Anton Gorenkov 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:
 *     Anton Gorenkov  - initial implementation
 *     Marc-Andre Laperle
 *     Nathan Ridge
 *     Danny Ferreira
 *******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers;

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

import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;

/**
 * Checks that class members of simple types (int, float, pointers, 
 * enumeration types, ...) are properly initialized in constructor. 
 * Not initialized members may cause to unstable or random behavior 
 * of methods that are working with their value.
 * 
 * @author Anton Gorenkov
 */
public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
	public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization"; //$NON-NLS-1$
	public static final String PARAM_SKIP = "skip"; //$NON-NLS-1$

	@Override
	public void processAst(IASTTranslationUnit ast) {
		ast.accept(new OnEachClass());
	}

	class OnEachClass extends ASTVisitor {
		// NOTE: Classes can be nested and even can be declared in constructors of the other classes
		private final Stack<Set<IField>> constructorsStack = new Stack<Set<IField>>();
		private boolean skipConstructorsWithFCalls = skipConstructorsWithFCalls();

		OnEachClass() {
			shouldVisitDeclarations = true;
			shouldVisitNames = true;
			shouldVisitExpressions = true;
		}

		@Override
		public int visit(IASTDeclaration declaration) {
			ICPPConstructor constructor = getConstructor(declaration);
			if (constructor != null) {
				Set<IField> fieldsInConstructor = constructorsStack.push(new HashSet<IField>());
				
				// Add all class fields
				try {
					CPPSemantics.pushLookupPoint(declaration);
					for (IField field : constructor.getClassOwner().getDeclaredFields()) {
						if (isSimpleType(field.getType()) && !field.isStatic()) {
							// In C++11, a field may have an initial value specified at its declaration.
							// Such a field does not need to be initialized in the constructor as well.
							if (field.getInitialValue() == null) {
								fieldsInConstructor.add(field);
							}
						}
					}
				} finally {
					CPPSemantics.popLookupPoint();
				}
			}
			return PROCESS_CONTINUE;
		}

		@Override
		public int leave(IASTDeclaration declaration) {
			if (getConstructor(declaration) != null) {
				for (IField field : constructorsStack.pop()) {
					reportProblem(ER_ID, declaration, field.getName());
				}
			}
			return PROCESS_CONTINUE;
		}
		
		@Override
		public int visit(IASTExpression expression) {
			boolean skipCurrentConstructor = false;
			
			if (skipConstructorsWithFCalls && !constructorsStack.empty() && expression instanceof IASTFunctionCallExpression) {
				Set<IField> actualConstructorFields = constructorsStack.peek();
				if (!actualConstructorFields.isEmpty()) {
					IASTFunctionCallExpression fCall = (IASTFunctionCallExpression) expression;
					IASTExpression fNameExp = fCall.getFunctionNameExpression();
					IBinding fBinding = null;
					if (fNameExp instanceof IASTIdExpression) {
						IASTIdExpression fName = (IASTIdExpression) fNameExp;
						fBinding = fName.getName().resolveBinding();
					} else if (fNameExp instanceof ICPPASTFieldReference) {
						ICPPASTFieldReference fName = (ICPPASTFieldReference) fNameExp;
						fBinding = fName.getFieldName().resolveBinding();
					}
					if (fBinding != null) {
						if (fBinding instanceof ICPPMethod) {
							ICPPMethod method = (ICPPMethod) fBinding;
							ICompositeType constructorOwner = actualConstructorFields.iterator().next().getCompositeTypeOwner();
							if (constructorOwner.equals(method.getClassOwner()) && !method.getType().isConst()) {
								skipCurrentConstructor = true;
							}
						} else if (fBinding instanceof ICPPFunction) {
							for (IASTInitializerClause argument : fCall.getArguments()) {
								if (referencesThis(argument)) {
									skipCurrentConstructor = true;
									break;
								}
							}
						}
					}
				}
			}
			
			// Bug 368420 - Skip constructor if pattern is *this = toBeCopied;
			if (expression instanceof IASTBinaryExpression) {
				IASTBinaryExpression binaryExpression = (IASTBinaryExpression) expression;
				if (referencesThis(binaryExpression.getOperand1()) && binaryExpression.getOperand1().isLValue()) {
					skipCurrentConstructor = true;
				}
			}
			
			if (skipCurrentConstructor && !constructorsStack.empty()) {
				constructorsStack.peek().clear();
			}
			return PROCESS_CONTINUE;
		}
		
		/**
		 * Checks whether expression references this (directly, by pointer or by reference)
		 */
		public boolean referencesThis(IASTNode expr) {
			if (expr instanceof IASTLiteralExpression) {
				IASTLiteralExpression litArg = (IASTLiteralExpression) expr;
				if (litArg.getKind() == IASTLiteralExpression.lk_this) {
					return true;
				}
			} else if (expr instanceof ICPPASTUnaryExpression) {
				ICPPASTUnaryExpression unExpr = (ICPPASTUnaryExpression) expr;
				switch (unExpr.getOperator()) {
					case IASTUnaryExpression.op_amper:
					case IASTUnaryExpression.op_star:
					case IASTUnaryExpression.op_bracketedPrimary:
						return referencesThis(unExpr.getOperand());
				}
			}
			return false;
		}

		@Override
		public int visit(IASTName name) {
			if (!constructorsStack.empty()) {
				Set<IField> actualConstructorFields = constructorsStack.peek();
				if (!actualConstructorFields.isEmpty()) {
					IBinding binding = name.resolveBinding();
					if (binding != null && !(binding instanceof IProblemBinding)) {
						IField equivalentFieldBinding = getContainedEquivalentBinding(
								actualConstructorFields, binding, name.getTranslationUnit().getIndex());
						if (equivalentFieldBinding != null) {
							if ((CPPVariableReadWriteFlags.getReadWriteFlags(name) & PDOMName.WRITE_ACCESS) != 0) {
								actualConstructorFields.remove(equivalentFieldBinding);
							}
						}
					}
				}
			}
			return PROCESS_CONTINUE;
		}
		
		private IField getContainedEquivalentBinding(Iterable<IField> fields, IBinding binding, IIndex index) {
			for (IField field : fields) {
				if (areEquivalentBindings(binding, field, index)) {
					return field;
				}
			}
			
			return null;
		}
		
		private boolean areEquivalentBindings(IBinding binding1, IBinding binding2, IIndex index) {
			if (binding1.equals(binding2)) {
				return true;
			}
			if ((binding1 instanceof IIndexBinding) != (binding2 instanceof IIndexBinding) && index != null) {
				if (binding1 instanceof IIndexBinding) {
					binding2 = index.adaptBinding(binding2);
				} else {
					binding1 = index.adaptBinding(binding1);
				}
				if (binding1 == null || binding2 == null) {
					return false;
				}
				if (binding1.equals(binding2)) {
					return true;
				}
			}
			return false;
		}
		
		/** Checks whether class member of the specified type should be initialized
		 * 
		 * @param type	Type to check
		 * @return true if type is:
		 *     - basic type (int, float, ...)
		 *     - pointer
		 *     - enum
		 *     - reference (should be initialized in initialization list)
		 *     - typedef to the another native type.
		 *     
		 * @note: Not supported types (but maybe should be):
		 *     - array
		 *     - union
		 *     - unknown type (need user preference?)
		 *     - template parameter (need user preference?)
		 */
		private boolean isSimpleType(IType type) {
			return (type instanceof IBasicType ||
					type instanceof IPointerType ||
					type instanceof IEnumeration ||
					type instanceof ICPPReferenceType ||
					(type instanceof ITypedef && isSimpleType(((ITypedef) type).getType())));
		}

		/** Checks that specified declaration is a class constructor 
		 *  (it is a class member and its name is equal to the class name)
		 */
		private ICPPConstructor getConstructor(IASTDeclaration decl) {
			if (decl instanceof ICPPASTFunctionDefinition) {
				ICPPASTFunctionDefinition functionDefinition = (ICPPASTFunctionDefinition) decl;
				if (functionDefinition.isDeleted())
					return null;
				IBinding binding = functionDefinition.getDeclarator().getName().resolveBinding();
				if (binding instanceof ICPPConstructor) {
					ICPPConstructor constructor = (ICPPConstructor) binding;
					// Skip defaulted copy and move constructors.
					if (functionDefinition.isDefaulted() && SemanticQueries.isCopyOrMoveConstructor(constructor))
						return null;
					if (constructor.getClassOwner().getKey() == ICompositeType.k_union)
						return null;
					// Skip delegating constructors.
					for (ICPPASTConstructorChainInitializer memberInitializer : functionDefinition.getMemberInitializers()) {
						IASTName memberName = memberInitializer.getMemberInitializerId();
						if (memberName != null) {
							IBinding memberBinding = memberName.resolveBinding();
							ICPPClassType classType = null; 
							if (memberBinding instanceof ICPPClassType) {
								classType = (ICPPClassType) memberBinding;
							} else if (memberBinding instanceof ICPPConstructor) {
								classType = ((ICPPConstructor) memberBinding).getClassOwner();
							}
							if (classType instanceof ICPPDeferredClassInstance) {
								classType = ((ICPPDeferredClassInstance) classType).getClassTemplate();
							}
							if (classType != null && classType.isSameType(constructor.getClassOwner()))
								return null;
						}
					}
					return constructor;
				}
			}
			
			return null;
		}
	}

	@Override
	public void initPreferences(IProblemWorkingCopy problem) {
		super.initPreferences(problem);
		addPreference(problem, PARAM_SKIP, CheckersMessages.ClassMembersInitializationChecker_SkipConstructorsWithFCalls, Boolean.TRUE);
	}

	public boolean skipConstructorsWithFCalls() {
		return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_SKIP);
	}
}
