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

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.BreakStatement;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ContinueStatement;
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.LabeledStatement;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.RecordDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;

import org.eclipse.jdt.internal.ui.util.ASTHelper;


/**
 * Find all nodes connected to a given binding or node. e.g. Declaration of a field and all references.
 * For types this includes also the constructor declaration, for methods also overridden methods
 * or methods overriding (if existing in the same AST), for constructors also the type and all other constructors.
  */

public class LinkedNodeFinder  {

	private LinkedNodeFinder() {
	}


	public static SimpleName getAssociatedRecordComponentNode(SimpleName simpleName) {
		SimpleName rcName= null;
		if (simpleName == null) {
			return null;
		}
		if (!ASTHelper.isRecordDeclarationNodeSupportedInAST(simpleName.getAST())) {
			return null;
		}
		IBinding binding= simpleName.resolveBinding();
		IVariableBinding rcBinding= null;
		ITypeBinding recordTypeBinding= null;
		ITypeBinding tBinding= null;
		String recCompName= null;
		if (binding instanceof IVariableBinding) {
			IVariableBinding vbinding= (IVariableBinding) binding;
			IVariableBinding bBinding= vbinding.getVariableDeclaration();
			if (bBinding == null) {
				return null;
			}
			if (!bBinding.isField()) {
				if (bBinding.isParameter()) {
					IMethodBinding mBinding= bBinding.getDeclaringMethod();
					if (mBinding != null
							&& (mBinding.isCompactConstructor()
									|| mBinding.isCanonicalConstructor())) {
						ITypeBinding typeBinding= mBinding.getDeclaringClass();
						if (typeBinding != null
								&& typeBinding.isRecord()) {
							recordTypeBinding= typeBinding;
							recCompName= bBinding.getName();
							tBinding= bBinding.getType();
						}
					}
				}
				if (recordTypeBinding == null) {
					return null;
				}
			}
			if (recordTypeBinding == null) {
				ITypeBinding cBinding= vbinding.getDeclaringClass();
				if (cBinding == null) {
					return null;
				}
				ITypeBinding typeBinding= cBinding.getTypeDeclaration();
				if (typeBinding== null || !typeBinding.isRecord()) {
					return null;
				}
				int modifiers= bBinding.getModifiers();
				if (Flags.isFinal(modifiers)
						&& !Flags.isStatic(modifiers)) {
					rcBinding= bBinding;
				}
			}
		} else if (binding instanceof IMethodBinding) {
			IMethodBinding mBinding = (IMethodBinding)binding;
			ITypeBinding cBinding= mBinding.getDeclaringClass();
			if (cBinding == null) {
				return null;
			}
			ITypeBinding typeBinding= cBinding.getTypeDeclaration();
			IMethodBinding bBinding= mBinding.getMethodDeclaration();
			if (bBinding == null ||
					typeBinding == null ||
					bBinding.getParameterTypes().length != 0 ||
					!typeBinding.isRecord()) {
				return null;
			}
			if (typeBinding.isRecord()) {
				recordTypeBinding= typeBinding;
				recCompName= simpleName.getIdentifier();
				tBinding= bBinding.getReturnType();
			}

		} else {
			return null;
		}
		if (recCompName != null
				&& recordTypeBinding != null
				&& tBinding != null) {
			IVariableBinding varBindings[]= recordTypeBinding.getDeclaredFields();
			if (varBindings != null) {
				for (IVariableBinding varBinding : varBindings) {
					String name= varBinding.getName();
					if (simpleName.getIdentifier().equals(name)) {
						int modifiers= varBinding.getModifiers();
						if (tBinding.isEqualTo(varBinding.getType())
								&& Flags.isFinal(modifiers)
								&& !Flags.isStatic(modifiers)) {
							rcBinding= varBinding;
							break;
						}
					}
				}
			}
		}
		RecordDeclaration recordDeclaration= null;
		if (rcBinding != null) {
			ITypeBinding cBinding= rcBinding.getDeclaringClass();
			if (cBinding != null) {
				ITypeBinding typeBinding= cBinding.getTypeDeclaration();
				if (typeBinding != null) {
					ASTNode root= simpleName.getRoot();
					if (root instanceof CompilationUnit) {
						CompilationUnit astRoot= (CompilationUnit) root;
						ASTNode foundNode= astRoot.findDeclaringNode(typeBinding);
						if (foundNode instanceof RecordDeclaration) {
							recordDeclaration= (RecordDeclaration) foundNode;
						}
					}
				}
			}
		}
		if (recordDeclaration != null) {
			List<ASTNode> ff=recordDeclaration.recordComponents();
			if (ff != null) {
				for (ASTNode nd : ff) {
					if (nd instanceof SingleVariableDeclaration) {
						SimpleName name= ((SingleVariableDeclaration) nd).getName();
						if (simpleName.getIdentifier().equals(name.getIdentifier())) {
							rcName= name;
							break;
						}
					}
				}
			}
		}
		return rcName;
	}



	/**
	 * Find all nodes connected to the given binding. e.g. Declaration of a field and all references.
	 * For types this includes also the constructor declaration, for methods also overridden methods
	 * or methods overriding (if existing in the same AST)
	 * @param root The root of the AST tree to search
	 * @param binding The binding of the searched nodes
	 * @return Return
	 */
	public static SimpleName[] findByBinding(ASTNode root, IBinding binding) {
		ArrayList<SimpleName> res= new ArrayList<>();
		BindingFinder nodeFinder= new BindingFinder(binding, res);
		root.accept(nodeFinder);
		return res.toArray(new SimpleName[res.size()]);
	}

	/**
	 * Find all nodes connected to the given name node. If the node has a binding then all nodes connected
	 * to this binding are returned. If the node has no binding, then all nodes that also miss a binding and have
	 * the same name are returned.
	 * @param root The root of the AST tree to search
	 * @param name The node to find linked nodes for
	 * @return Return
	 */
	public static SimpleName[] findByNode(ASTNode root, SimpleName name) {
		IBinding binding = name.resolveBinding();
		if (binding != null) {
			SimpleName recNode= getAssociatedRecordComponentNode(name);
			if (recNode != null) {
				IBinding recBinding= recNode.resolveBinding();
				return findByBinding(root, recBinding);
			}
			return findByBinding(root, binding);
		}
		SimpleName[] names= findByProblems(root, name);
		if (names != null) {
			return names;
		}
		int parentKind= name.getParent().getNodeType();
		if (parentKind == ASTNode.LABELED_STATEMENT || parentKind == ASTNode.BREAK_STATEMENT || parentKind == ASTNode.CONTINUE_STATEMENT) {
			ArrayList<SimpleName> res= new ArrayList<>();
			LabelFinder nodeFinder= new LabelFinder(name, res);
			root.accept(nodeFinder);
			return res.toArray(new SimpleName[res.size()]);
		}
		return new SimpleName[] { name };
	}



	private static final int FIELD= 1;
	private static final int METHOD= 2;
	private static final int TYPE= 4;
	private static final int LABEL= 8;
	private static final int NAME= FIELD | TYPE;

	private static int getProblemKind(IProblem problem) {
		switch (problem.getID()) {
			case IProblem.UndefinedField:
				return FIELD;
			case IProblem.UndefinedMethod:
				return METHOD;
			case IProblem.UndefinedLabel:
				return LABEL;
			case IProblem.UndefinedName:
			case IProblem.UnresolvedVariable:
				return NAME;
			case IProblem.UndefinedType:
				return TYPE;
		}
		return 0;
	}

	private static int getNameNodeProblemKind(IProblem[] problems, SimpleName nameNode) {
		int nameOffset= nameNode.getStartPosition();
		int nameInclEnd= nameOffset + nameNode.getLength() - 1;

		for (IProblem curr : problems) {
			if (curr.getSourceStart() == nameOffset && curr.getSourceEnd() == nameInclEnd) {
				int kind= getProblemKind(curr);
				if (kind != 0) {
					return kind;
				}
			}
		}
		return 0;
	}


	public static SimpleName[] findByProblems(ASTNode parent, SimpleName nameNode) {
		if (nameNode.getAST().apiLevel() >= AST.JLS10 && nameNode.isVar()) {
			return null;
		}
		ArrayList<SimpleName> res= new ArrayList<>();

		ASTNode astRoot = parent.getRoot();
		if (!(astRoot instanceof CompilationUnit)) {
			return null;
		}

		IProblem[] problems= ((CompilationUnit) astRoot).getProblems();
		int nameNodeKind= getNameNodeProblemKind(problems, nameNode);
		if (nameNodeKind == 0) { // no problem on node
			return null;
		}

		int bodyStart= parent.getStartPosition();
		int bodyEnd= bodyStart + parent.getLength();

		String name= nameNode.getIdentifier();

		for (IProblem curr : problems) {
			int probStart= curr.getSourceStart();
			int probEnd= curr.getSourceEnd() + 1;

			if (probStart > bodyStart && probEnd < bodyEnd) {
				int currKind= getProblemKind(curr);
				if ((nameNodeKind & currKind) != 0) {
					ASTNode node= NodeFinder.perform(parent, probStart, (probEnd - probStart));
					if (node instanceof SimpleName && name.equals(((SimpleName) node).getIdentifier())) {
						if (node.getAST().apiLevel() < AST.JLS10 || !((SimpleName) node).isVar()) {
							res.add((SimpleName) node);
						}
					}
				}
			}
		}
		return res.toArray(new SimpleName[res.size()]);
	}

	private static class LabelFinder extends ASTVisitor {

		private SimpleName fLabel;
		private ASTNode fDefiningLabel;
		private ArrayList<SimpleName> fResult;

		public LabelFinder(SimpleName label, ArrayList<SimpleName> result) {
			super(true);
			fLabel= label;
			fResult= result;
			fDefiningLabel= null;
		}

		private boolean isSameLabel(SimpleName label) {
			return label != null && fLabel.getIdentifier().equals(label.getIdentifier());
		}

		@Override
		public boolean visit(BreakStatement node) {
			SimpleName label= node.getLabel();
			if (fDefiningLabel != null && isSameLabel(label) && ASTNodes.isParent(label, fDefiningLabel)) {
				fResult.add(label);
			}
			return false;
		}

		@Override
		public boolean visit(ContinueStatement node) {
			SimpleName label= node.getLabel();
			if (fDefiningLabel != null && isSameLabel(label) && ASTNodes.isParent(label, fDefiningLabel)) {
				fResult.add(label);
			}
			return false;
		}

		@Override
		public boolean visit(LabeledStatement node) {
			if (fDefiningLabel == null) {
				SimpleName label= node.getLabel();
				if (fLabel == label || isSameLabel(label) && ASTNodes.isParent(fLabel, node)) {
					fDefiningLabel= node;
					fResult.add(label);
				}
			}
			node.getBody().accept(this);
			return false;
		}
	}

	private static class BindingFinder extends ASTVisitor {

		private IBinding fBinding;
		private ArrayList<SimpleName> fResult;

		public BindingFinder(IBinding binding, ArrayList<SimpleName> result) {
			super(true);
			fBinding= getDeclaration(binding);
			fResult= result;
		}

		@Override
		public boolean visit(SimpleName node) {
			if (node.getAST().apiLevel() >= AST.JLS10 && node.isVar()) {
				return false;
			}
			IBinding binding= node.resolveBinding();
			if (binding == null) {
				return false;
			}
			binding= getDeclaration(binding);
			SimpleName rcNode= getAssociatedRecordComponentNode(node);
			if (fBinding == binding) {
				fResult.add(node);
			} else if (rcNode != null) {
				IBinding rcBinding= rcNode.resolveBinding();
				if (rcBinding != null) {
					rcBinding= getDeclaration(rcBinding);
					if (fBinding == rcBinding) {
						fResult.add(node);
					}
				}
			} else if (binding.getKind() != fBinding.getKind()) {
				return false;
			} else if (binding.getKind() == IBinding.METHOD) {
				IMethodBinding curr= (IMethodBinding) binding;
				IMethodBinding methodBinding= (IMethodBinding) fBinding;
				if (methodBinding.overrides(curr) || curr.overrides(methodBinding)) {
					fResult.add(node);
				}
			}
			return false;
		}

		private static IBinding getDeclaration(IBinding binding) {
			if (binding instanceof ITypeBinding) {
				return ((ITypeBinding) binding).getTypeDeclaration();
			} else if (binding instanceof IMethodBinding) {
				IMethodBinding methodBinding= (IMethodBinding) binding;
				if (methodBinding.isConstructor()) { // link all constructors with their type
					return methodBinding.getDeclaringClass().getTypeDeclaration();
				} else {
					return methodBinding.getMethodDeclaration();
				}
			} else if (binding instanceof IVariableBinding) {
				return ((IVariableBinding) binding).getVariableDeclaration();
			}
			return binding;
		}
	}
}
