/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] extracting return value results in compile error - https://bugs.eclipse.org/bugs/show_bug.cgi?id=264606
 *     Samrat Dhillon <samrat.dhillon@gmail.com> -  [extract method] Extracted method should be declared static if extracted expression is also used in another static method https://bugs.eclipse.org/bugs/show_bug.cgi?id=393098
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.code;

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

import org.eclipse.core.runtime.Assert;

import org.eclipse.jdt.core.dom.ASTMatcher;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;


/* package */ class SnippetFinder extends GenericVisitor {

	public static class Match {
		private List<ASTNode> fNodes;
		private Map<IVariableBinding, SimpleName> fLocalMappings;

		public Match() {
			fNodes= new ArrayList<>(10);
			fLocalMappings= new HashMap<>();
		}
		public void add(ASTNode node) {
			fNodes.add(node);
		}
		public boolean hasCorrectNesting(ASTNode node) {
			if (fNodes.size() == 0)
				return true;
			ASTNode parent= node.getParent();
			if(fNodes.get(0).getParent() != parent)
				return false;
			// Here we know that we have two elements. In this case the
			// parent must be a block or a switch statement. Otherwise a
			// snippet like "if (true) foo(); else foo();" would match
			// the pattern "foo(); foo();"
			int nodeType= parent.getNodeType();
			return nodeType == ASTNode.BLOCK || nodeType == ASTNode.SWITCH_STATEMENT;
		}
		public ASTNode[] getNodes() {
			return fNodes.toArray(new ASTNode[fNodes.size()]);
		}
		public void addLocal(IVariableBinding org, SimpleName local) {
			fLocalMappings.put(org, local);
		}
		public SimpleName getMappedName(IVariableBinding org) {
			return fLocalMappings.get(org);
		}
		public IVariableBinding getMappedBinding(IVariableBinding org) {
			SimpleName name= fLocalMappings.get(org);
			return ASTNodes.getVariableBinding(name);
		}
		public boolean isEmpty() {
			return fNodes.isEmpty() && fLocalMappings.isEmpty();
		}
		
		/**
		 * Tests whether the node to be replaced is invalid.
		 * 
		 * @return true if the node is invalid, false otherwise
		 * 
		 */
		public boolean isInvalidNode() {
			ASTNode first= fNodes.get(0);
			ASTNode candidate= first.getParent();
			if (candidate == null)
				return false;
			// return invalid if the opening and closing parenthesis of the method signature is part of the node to be replaced
			if (candidate.getNodeType() == ASTNode.METHOD_DECLARATION)
				return true;
			return false;
		}
		
		public MethodDeclaration getEnclosingMethod() {
			ASTNode first= fNodes.get(0);
			return (MethodDeclaration)ASTNodes.getParent(first, ASTNode.METHOD_DECLARATION);
		}
		
		public boolean isNodeInStaticContext(){
			ASTNode first= fNodes.get(0);
			return ASTResolving.isInStaticContext(first);
		}
	}

	private class Matcher extends ASTMatcher {
		@Override
		public boolean match(SimpleName candidate, Object s) {
			if (!(s instanceof SimpleName))
				return false;

			SimpleName snippet= (SimpleName)s;
			if (candidate.isDeclaration() != snippet.isDeclaration())
				return false;

			IBinding cb= candidate.resolveBinding();
			IBinding sb= snippet.resolveBinding();
			if (cb == null || sb == null)
				return false;
			IVariableBinding vcb= ASTNodes.getVariableBinding(candidate);
			IVariableBinding vsb= ASTNodes.getVariableBinding(snippet);
			if (vcb == null || vsb == null)
				return Bindings.equals(cb, sb);
			if (!vcb.isField() && !vsb.isField() && Bindings.equals(vcb.getType(), vsb.getType())) {
				SimpleName mapped= fMatch.getMappedName(vsb);
				if (mapped != null) {
					IVariableBinding mappedBinding= ASTNodes.getVariableBinding(mapped);
					if (!Bindings.equals(vcb, mappedBinding))
						return false;
				}
				fMatch.addLocal(vsb, candidate);
				return true;
			}
			return Bindings.equals(cb, sb);
		}
	}

	private List<Match> fResult= new ArrayList<>(2);
	private Match fMatch;
	private ASTNode[] fSnippet;
	private int fIndex;
	private Matcher fMatcher;
	private int fTypes;

	private SnippetFinder(ASTNode[] snippet) {
		super(true);
		fSnippet= snippet;
		fMatcher= new Matcher();
		reset();
	}

	public static List<Match> perform(ASTNode start, ASTNode[] snippet) {
		Assert.isTrue(start instanceof AbstractTypeDeclaration || start instanceof AnonymousClassDeclaration);
		SnippetFinder finder= new SnippetFinder(snippet);
		start.accept(finder);
		for (Iterator<Match> iter = finder.fResult.iterator(); iter.hasNext();) {
			Match match = iter.next();
			ASTNode[] nodes= match.getNodes();
			// doesn't match if the candidate is the left hand side of an
			// assignment and the snippet consists of a single node.
			// Otherwise y= i; i= z; results in y= e(); e()= z;
			if (nodes.length == 1 && isLeftHandSideOfAssignment(nodes[0])) {
				iter.remove();
			}
		}
		return finder.fResult;
	}

	static boolean isLeftHandSideOfAssignment(ASTNode node) {
		Assignment assignment= (Assignment)ASTNodes.getParent(node, ASTNode.ASSIGNMENT);
		if (assignment != null) {
			Expression leftHandSide= assignment.getLeftHandSide();
			if (leftHandSide == node) {
				return true;
			}
			if (ASTNodes.isParent(node, leftHandSide)) {
				switch (leftHandSide.getNodeType()) {
					case ASTNode.SIMPLE_NAME:
						return true;
					case ASTNode.FIELD_ACCESS:
						return node == ((FieldAccess)leftHandSide).getName();
					case ASTNode.QUALIFIED_NAME:
						return node == ((QualifiedName)leftHandSide).getName();
					case ASTNode.SUPER_FIELD_ACCESS:
						return node == ((SuperFieldAccess)leftHandSide).getName();
					default:
						return false;
				}
			}
		}
		return false;
	}

	@Override
	public boolean visit(TypeDeclaration node) {
		if (++fTypes > 1)
			return false;
		return super.visit(node);
	}

	@Override
	public void endVisit(TypeDeclaration node) {
		--fTypes;
		super.endVisit(node);
	}

	@Override
	public boolean visit(EnumDeclaration node) {
		if (++fTypes > 1)
			return false;
		return super.visit(node);
	}

	@Override
	public void endVisit(EnumDeclaration node) {
		--fTypes;
		super.endVisit(node);
	}

	@Override
	public boolean visit(AnnotationTypeDeclaration node) {
		if (++fTypes > 1)
			return false;
		return super.visit(node);
	}

	@Override
	public void endVisit(AnnotationTypeDeclaration node) {
		--fTypes;
		super.endVisit(node);
	}

	@Override
	protected boolean visitNode(ASTNode node) {
		if (matches(node)) {
			return false;
		} else if (!isResetted()){
			reset();
			if (matches(node))
				return false;
		}
		return true;
	}

	private boolean matches(ASTNode node) {
		if (isSnippetNode(node))
			return false;
		if (node.subtreeMatch(fMatcher, fSnippet[fIndex]) && fMatch.hasCorrectNesting(node)) {
			fMatch.add(node);
			fIndex++;
			if (fIndex == fSnippet.length) {
				fResult.add(fMatch);
				reset();
			}
			return true;
		}
		return false;
	}

	private boolean isResetted() {
		return fIndex == 0 && fMatch.isEmpty();
	}

	private void reset() {
		fIndex= 0;
		fMatch= new Match();
	}

	private boolean isSnippetNode(ASTNode node) {
		for (int i= 0; i < fSnippet.length; i++) {
			if (node == fSnippet[i])
				return true;
		}
		return false;
	}
}
