/*******************************************************************************
 * Copyright (c) 2020, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Red Hat Inc. - initial version based on SurroundWithTryCatchAnalyzer
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.surround;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodReference;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.UnionType;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.util.SurroundWithAnalyzer;

public class SurroundWithTryWithResourcesAnalyzer extends SurroundWithAnalyzer {

	private ITypeBinding[] fExceptions;
	private ASTNode fEnclosingNode;
	private CompilationUnit fCompilationUnit;

	public SurroundWithTryWithResourcesAnalyzer(ICompilationUnit unit, Selection selection) throws CoreException {
		super(unit, selection, true);
	}

	public ITypeBinding[] getExceptions(Selection selection) {
		if (fEnclosingNode != null && !getStatus().hasFatalError()) {
			fExceptions= ExceptionAnalyzer.perform(fEnclosingNode, selection, false);
			if (fExceptions == null || fExceptions.length == 0) {
				if (fEnclosingNode instanceof MethodReference) {
					invalidSelection(RefactoringCoreMessages.SurroundWithTryCatchAnalyzer_doesNotContain);
				} else {
					List<ASTNode> autoClosableNodes= getCoveredAutoClosableNodes();
					if (autoClosableNodes.isEmpty()) {
						fExceptions= new ITypeBinding[] { fCompilationUnit.getAST().resolveWellKnownType("java.lang.Exception") }; //$NON-NLS-1$
					} else {
						fExceptions= new ITypeBinding[0];
					}
				}
			}
		}
		return fExceptions;
	}

	public ITypeBinding[] getCaughtExceptions() {
		List<ITypeBinding> exceptions= new ArrayList<>();
		TryStatement enclosingTry= (TryStatement)ASTResolving.findAncestor(getFirstSelectedNode(), ASTNode.TRY_STATEMENT);
		while (enclosingTry != null) {
			List<CatchClause> catchClauses= enclosingTry.catchClauses();
			for (CatchClause catchClause : catchClauses) {
				SingleVariableDeclaration sdv= catchClause.getException();
				Type type= sdv.getType();
				if (type instanceof UnionType) {
					UnionType unionType= (UnionType)type;
					List<Type> types= unionType.types();
					for (Type t : types) {
						ITypeBinding binding= t.resolveBinding();
						if (binding == null) {
							break;
						}
						exceptions.add(binding);
					}
				} else {
					ITypeBinding binding= type.resolveBinding();
					if (binding != null) {
						exceptions.add(binding);
					}
				}
			}
			enclosingTry= (TryStatement)ASTResolving.findAncestor(enclosingTry.getParent(), ASTNode.TRY_STATEMENT);
		}
		return exceptions.toArray(new ITypeBinding[0]);
	}

	public ITypeBinding[] getThrownExceptions() {
		List<ITypeBinding> exceptions= new ArrayList<>();
		if (fEnclosingNode.getNodeType() == ASTNode.METHOD_DECLARATION) {
			List<Type> thrownExceptions= ((MethodDeclaration) fEnclosingNode).thrownExceptionTypes();
			for (Type type : thrownExceptions) {
				ITypeBinding thrownException= type.resolveBinding();
				if (thrownException != null) {
					exceptions.add(thrownException);
				}
			}
		} else {
			ITypeBinding typeBinding= null;
			if (fEnclosingNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) {
				typeBinding= ((LambdaExpression) fEnclosingNode.getParent()).resolveTypeBinding();
			} else if (fEnclosingNode instanceof MethodReference) {
				typeBinding= ((MethodReference) fEnclosingNode).resolveTypeBinding();
			}
			if (typeBinding != null) {
				IMethodBinding methodBinding= typeBinding.getFunctionalInterfaceMethod();
				if (methodBinding != null) {
					Collections.addAll(exceptions, methodBinding.getExceptionTypes());
				}
			}
		}
		return exceptions.toArray(new ITypeBinding[0]);
	}

	public List<ITypeBinding> calculateCatchesAndRethrows(List<ITypeBinding> exceptions, List<ITypeBinding> mustRethrowList) {
		List<ITypeBinding> exceptionList= new ArrayList<>(exceptions);
		ITypeBinding[] caughtExceptions= getCaughtExceptions();
		if (caughtExceptions.length > 0) {
			for (Iterator<ITypeBinding> iter= exceptionList.iterator(); iter.hasNext();) {
				ITypeBinding binding= iter.next();
				for (ITypeBinding caughtException : caughtExceptions) {
					if (binding.isAssignmentCompatible(caughtException)) {
						iter.remove();
						break;
					}
				}
			}
			for (ITypeBinding binding : exceptionList) {
				for (ITypeBinding caughtException : caughtExceptions) {
					if (caughtException.isAssignmentCompatible(binding)) {
						mustRethrowList.add(caughtException);
						break;
					}
				}
			}
		}
		ITypeBinding[] thrownExceptions= getThrownExceptions();
		for (Iterator<ITypeBinding> iter= exceptionList.iterator(); iter.hasNext();) {
			ITypeBinding binding= iter.next();
			for (ITypeBinding thrownException : thrownExceptions) {
				if (binding.isAssignmentCompatible(thrownException)) {
					iter.remove();
					break;
				}
			}
		}
		for (ITypeBinding binding : exceptionList) {
			for (ITypeBinding thrownException : thrownExceptions) {
				if (thrownException.isAssignmentCompatible(binding)) {
					mustRethrowList.add(thrownException);
					break;
				}
			}
		}
		return exceptionList;
	}

	public ASTNode getEnclosingNode() {
		return fEnclosingNode;
	}

	@Override
	public void endVisit(CompilationUnit node) {
		fEnclosingNode= null;
		fCompilationUnit= node;
		if (!getStatus().hasFatalError() && hasSelectedNodes())
			fEnclosingNode= SurroundWithAnalyzer.getEnclosingNode(getFirstSelectedNode());

		super.endVisit(node);
	}

	/**
	 * Return the first auto closable nodes. When a node that isn't Autoclosable is found the method
	 * returns.
	 *
	 * @return List of the first AutoClosable nodes found
	 */
	public List<ASTNode> getCoveredAutoClosableNodes() {
		ASTNode[] astNodes= getSelectedNodes();
		List<ASTNode> autoClosableNodes= new ArrayList<>();
		for (ASTNode astNode : astNodes) {
			if (isAutoClosable(astNode)) {
				autoClosableNodes.add(astNode);
			} else {
				return autoClosableNodes;
			}
		}
		return autoClosableNodes;
	}

	private boolean isAutoClosable(ASTNode astNode) {
		Map<SimpleName, IVariableBinding> simpleNames= getVariableStatementBinding(astNode);
		for (Entry<SimpleName, IVariableBinding> entry : simpleNames.entrySet()) {
			ITypeBinding typeBinding= null;
			switch (entry.getKey().getParent().getNodeType()) {
				case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
				case ASTNode.VARIABLE_DECLARATION_STATEMENT:
				case ASTNode.ASSIGNMENT:
					typeBinding= entry.getValue().getType();
					break;
				default:
					continue;
			}
			if (typeBinding == null) {
				continue;
			}
			for (ITypeBinding superType : Bindings.getAllSuperTypes(typeBinding)) {
				if (superType.getQualifiedName().equals("java.lang.AutoCloseable")) { //$NON-NLS-1$
					return true;
				}
			}
		}
		return false;
	}

	public Map<SimpleName, IVariableBinding> getVariableStatementBinding(ASTNode astNode) {
		Map<SimpleName, IVariableBinding> variableBindings= new HashMap<>();
		astNode.accept(new ASTVisitor() {
			@Override
			public boolean visit(VariableDeclarationStatement node) {
				for (Object o : node.fragments()) {
					if (o instanceof VariableDeclarationFragment) {
						VariableDeclarationFragment vdf= (VariableDeclarationFragment) o;
						SimpleName name= vdf.getName();
						IBinding binding= name.resolveBinding();
						if (binding instanceof IVariableBinding) {
							variableBindings.put(name, (IVariableBinding) binding);
							break;
						}
					}
				}
				return false;
			}
		});
		return variableBindings;
	}

}
