/*******************************************************************************
 * Copyright (c) 2007, 2013 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.codeassist;

import java.util.Stack;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.util.SimpleSet;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ThrownExceptionFinder extends ASTVisitor {

	private SimpleSet thrownExceptions;
	private Stack exceptionsStack;
	private SimpleSet caughtExceptions;
	private SimpleSet discouragedExceptions;

	/**
	 * Finds the thrown exceptions minus the ones that are already caught in previous catch blocks.
	 * Exception is already caught even if its super type is being caught. Also computes, separately,
	 * a list comprising of (a)those exceptions that have been caught already and (b)those exceptions that are thrown
	 * by the method and whose super type has been caught already. 
	 * @param tryStatement
	 * @param scope
	 */
	public void processThrownExceptions(TryStatement tryStatement, BlockScope scope) {
		this.thrownExceptions = new SimpleSet();
		this.exceptionsStack = new Stack();
		this.caughtExceptions = new SimpleSet();
		this.discouragedExceptions = new SimpleSet();
		tryStatement.traverse(this, scope);
		removeCaughtExceptions(tryStatement, true /*remove unchecked exceptions this time*/);
	}

	private void acceptException(ReferenceBinding binding) {
		if (binding != null && binding.isValidBinding()) {
			this.thrownExceptions.add(binding);
		}
	}

	public void endVisit(MessageSend messageSend, BlockScope scope) {
		if (messageSend.binding != null) {
			endVisitMethodInvocation(messageSend.binding);
		}
		super.endVisit(messageSend, scope);
	}

	public void endVisit(AllocationExpression allocationExpression, BlockScope scope) {
		if (allocationExpression.binding != null) {
			endVisitMethodInvocation(allocationExpression.binding);
		}
		super.endVisit(allocationExpression, scope);
	}

	public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
		acceptException((ReferenceBinding)throwStatement.exception.resolvedType);
		super.endVisit(throwStatement, scope);
	}


	private void endVisitMethodInvocation(MethodBinding methodBinding) {
		ReferenceBinding[] thrownExceptionBindings = methodBinding.thrownExceptions;
		int length = thrownExceptionBindings == null ? 0 : thrownExceptionBindings.length;
		for (int i = 0; i < length; i++) {
			acceptException(thrownExceptionBindings[i]);
		}
	}


	/**
	 * Returns all the already caught exceptions in catch blocks, found by the call to
	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}
	 * @return Returns an array of those exceptions that have been caught already in previous catch or
	 * multi-catch blocks of the same try block. (Exceptions caught in inner try-catches are obtained via
	 * {@link ThrownExceptionFinder#getDiscouragedExceptions()}.
	 */
	public ReferenceBinding[] getAlreadyCaughtExceptions() {
		ReferenceBinding[] allCaughtExceptions = new ReferenceBinding[this.caughtExceptions.elementSize];
		this.caughtExceptions.asArray(allCaughtExceptions);
		return allCaughtExceptions;
	}
	
	/**
	 * Returns all the thrown exceptions minus the ones that are already caught in previous catch blocks
	 * (of the same try), found by the call to 
	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}.
	 * @return Returns an array of thrown exceptions that are still not caught in any catch block.
	 */
	public ReferenceBinding[] getThrownUncaughtExceptions() {
		ReferenceBinding[] result = new ReferenceBinding[this.thrownExceptions.elementSize];
		this.thrownExceptions.asArray(result);
		return result;
	}
	
	/**
	 * Returns all exceptions that are discouraged to use because (a) they are already caught in some inner try-catch, 
	 * or (b) their super exception has already been caught.
	 * @return all discouraged exceptions
	 */
	public ReferenceBinding[] getDiscouragedExceptions() {
		ReferenceBinding[] allDiscouragedExceptions = new ReferenceBinding[this.discouragedExceptions.elementSize];
		this.discouragedExceptions.asArray(allDiscouragedExceptions);
		return allDiscouragedExceptions;
	}
	public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
		return visitType(typeDeclaration);
	}

	public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
		return visitType(memberTypeDeclaration);
	}

	public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
		return visitType(localTypeDeclaration);
	}

	private boolean visitType(TypeDeclaration typeDeclaration) {
		return false;
	}

	public boolean visit(TryStatement tryStatement, BlockScope scope) {
		this.exceptionsStack.push(this.thrownExceptions);
		SimpleSet exceptionSet = new SimpleSet();
		this.thrownExceptions = exceptionSet;
		tryStatement.tryBlock.traverse(this, scope);

		removeCaughtExceptions(tryStatement, false);

		this.thrownExceptions = (SimpleSet)this.exceptionsStack.pop();

		Object[] values = exceptionSet.values;
		for (int i = 0; i < values.length; i++) {
			if (values[i] != null) {
				this.thrownExceptions.add(values[i]);
			}
		}

		Block[] catchBlocks = tryStatement.catchBlocks;
		int length = catchBlocks == null ? 0 : catchBlocks.length;
		for (int i = 0; i < length; i++) {
			catchBlocks[i].traverse(this, scope);
		}
		return false;
	}
	
	private void removeCaughtExceptions(TryStatement tryStatement, boolean recordUncheckedCaughtExceptions) {
		Argument[] catchArguments = tryStatement.catchArguments;
		int length = catchArguments == null ? 0 : catchArguments.length;
		for (int i = 0; i < length; i++) {
			if (catchArguments[i].type instanceof UnionTypeReference) {
				UnionTypeReference unionTypeReference = (UnionTypeReference) catchArguments[i].type;
				TypeBinding caughtException;
				for (int j = 0; j < unionTypeReference.typeReferences.length; j++) {
					caughtException = unionTypeReference.typeReferences[j].resolvedType;
					if ((caughtException instanceof ReferenceBinding) && caughtException.isValidBinding()) {	// might be null when its the completion node
						if (recordUncheckedCaughtExceptions) {
							// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
							removeCaughtException((ReferenceBinding)caughtException);
							this.caughtExceptions.add(caughtException);
						} else {
							// is in some inner try-catch. Discourage already caught checked exceptions
							// from being proposed in an outer catch.
							if (!caughtException.isUncheckedException(true)) {
								this.discouragedExceptions.add(caughtException);
							}
						}
					}
				}
			} else {
				TypeBinding exception = catchArguments[i].type.resolvedType;
				if ((exception instanceof ReferenceBinding) && exception.isValidBinding()) {
					if (recordUncheckedCaughtExceptions) {
						// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
						removeCaughtException((ReferenceBinding)exception);
						this.caughtExceptions.add(exception);
					} else {
						// is in some inner try-catch. Discourage already caught checked exceptions
						// from being proposed in an outer catch
						if (!exception.isUncheckedException(true)) {
							this.discouragedExceptions.add(exception);
						}
					}
				}
			}
		}
	}

	private void removeCaughtException(ReferenceBinding caughtException) {
		Object[] exceptions = this.thrownExceptions.values;
		for (int i = 0; i < exceptions.length; i++) {
			ReferenceBinding exception = (ReferenceBinding)exceptions[i];
			if (exception != null) {
				if (TypeBinding.equalsEquals(exception, caughtException)) {
					this.thrownExceptions.remove(exception);
				} else if (caughtException.isSuperclassOf(exception)) {
					// catching the sub-exception when super has been caught already will give an error
					// so remove it from thrown list and lower the relevance for cases when it is found
					// from searchAllTypes(..)
					this.thrownExceptions.remove(exception);
					this.discouragedExceptions.add(exception);
				}
			}
		}
	}
}
