/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     xored software, Inc. - initial API and Implementation
 *     xored software, Inc. - Search All occurences bugfix, 
 *     						  hilight only class name when class is in search results ( Alex Panchenko <alex@xored.com>)
 *******************************************************************************/
package org.eclipse.dltk.core.search.matching;

import java.text.Annotation;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.declarations.FieldDeclaration;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.ast.expressions.CallExpression;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.references.Reference;
import org.eclipse.dltk.ast.references.TypeReference;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.compiler.env.lookup.Scope;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.search.SearchMatch;
import org.eclipse.dltk.core.search.SearchPattern;
import org.eclipse.dltk.core.search.indexing.IIndexConstants;
import org.eclipse.dltk.internal.core.search.matching.DLTKSearchPattern;
import org.eclipse.dltk.internal.core.search.matching.FieldLocator;
import org.eclipse.dltk.internal.core.search.matching.FieldPattern;
import org.eclipse.dltk.internal.core.search.matching.InternalSearchPattern;
import org.eclipse.dltk.internal.core.search.matching.MatchingNodeSet;
import org.eclipse.dltk.internal.core.search.matching.MethodDeclarationLocator;
import org.eclipse.dltk.internal.core.search.matching.MethodDeclarationPattern;
import org.eclipse.dltk.internal.core.search.matching.MethodLocator;
import org.eclipse.dltk.internal.core.search.matching.MethodPattern;
import org.eclipse.dltk.internal.core.search.matching.OrLocator;
import org.eclipse.dltk.internal.core.search.matching.OrPattern;
import org.eclipse.dltk.internal.core.search.matching.TypeDeclarationLocator;
import org.eclipse.dltk.internal.core.search.matching.TypeDeclarationPattern;
import org.eclipse.dltk.internal.core.search.matching.TypeReferenceLocator;
import org.eclipse.dltk.internal.core.search.matching.TypeReferencePattern;

public abstract class PatternLocator implements IIndexConstants {
	// store pattern info
	protected int matchMode;
	protected boolean isCaseSensitive;
	protected boolean isCamelCase;
	protected boolean isEquivalentMatch;
	protected boolean isErasureMatch;
	protected Pattern compiledPattern;

	// match to report
	SearchMatch match = null;
	/* match levels */
	public static final int IMPOSSIBLE_MATCH = 0;
	public static final int INACCURATE_MATCH = 1;
	public static final int POSSIBLE_MATCH = 2;
	public static final int ACCURATE_MATCH = 3;
	public static final int ERASURE_MATCH = 4;
	// Possible rule match flavors
	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866
	protected static final int POSSIBLE_FULL_MATCH = POSSIBLE_MATCH
			| (SearchPattern.R_FULL_MATCH << 16);
	protected static final int POSSIBLE_PREFIX_MATCH = POSSIBLE_MATCH
			| (SearchPattern.R_PREFIX_MATCH << 16);
	protected static final int POSSIBLE_PATTERN_MATCH = POSSIBLE_MATCH
			| (SearchPattern.R_PATTERN_MATCH << 16);
	protected static final int POSSIBLE_REGEXP_MATCH = POSSIBLE_MATCH
			| (SearchPattern.R_REGEXP_MATCH << 16);
	protected static final int POSSIBLE_CAMELCASE_MATCH = POSSIBLE_MATCH
			| (SearchPattern.R_CAMELCASE_MATCH << 16);
	public static final int NODE_SET_MASK = 0xFF;
	protected static final int POSSIBLE_MATCH_MASK = ~NODE_SET_MASK;
	/* match container */
	public static final int COMPILATION_UNIT_CONTAINER = 1;
	public static final int CLASS_CONTAINER = 2;
	public static final int METHOD_CONTAINER = 4;
	public static final int FIELD_CONTAINER = 8;
	public static final int ALL_CONTAINER = COMPILATION_UNIT_CONTAINER
			| CLASS_CONTAINER | METHOD_CONTAINER | FIELD_CONTAINER;
	/* match rule */
	public static final int RAW_MASK = SearchPattern.R_EQUIVALENT_MATCH
			| SearchPattern.R_ERASURE_MATCH;
	public static final int RULE_MASK = RAW_MASK; // no other values for the

	// while...
	public static PatternLocator patternLocator(SearchPattern pattern,
			IDLTKLanguageToolkit toolkit) {
		switch (((InternalSearchPattern) pattern).kind) {
		// case IIndexConstants.PKG_REF_PATTERN:
		// return new PackageReferenceLocator((PackageReferencePattern)
		// pattern);
		// case IIndexConstants.PKG_DECL_PATTERN:
		// return new PackageDeclarationLocator((PackageDeclarationPattern)
		// pattern);
		case IIndexConstants.TYPE_REF_PATTERN:
			return new TypeReferenceLocator((TypeReferencePattern) pattern);
		case IIndexConstants.TYPE_DECL_PATTERN:
			return new TypeDeclarationLocator((TypeDeclarationPattern) pattern);
		case IIndexConstants.METHOD_DECL_PATTERN:
			return new MethodDeclarationLocator(
					(MethodDeclarationPattern) pattern);
			// case IIndexConstants.SUPER_REF_PATTERN:
			// return new
			// SuperTypeReferenceLocator((SuperTypeReferencePattern)
			// pattern);
			// case IIndexConstants.CONSTRUCTOR_PATTERN:
			// return new ConstructorLocator((ConstructorPattern) pattern);
		case IIndexConstants.FIELD_PATTERN:
			return new FieldLocator((FieldPattern) pattern);
		case IIndexConstants.METHOD_PATTERN:
			return new MethodLocator((MethodPattern) pattern);
		case IIndexConstants.OR_PATTERN:
			return new OrLocator((OrPattern) pattern);
		}
		return null;
	}

	public static char[] qualifiedPattern(char[] simpleNamePattern,
			char[] qualificationPattern) {
		// NOTE: if case insensitive search then simpleNamePattern &
		// qualificationPattern are assumed to be lowercase
		if (simpleNamePattern == null) {
			if (qualificationPattern == null)
				return null;
			return CharOperation.concat(qualificationPattern, ONE_STAR, '.');
		} else {
			return qualificationPattern == null ? CharOperation.concat(
					ONE_STAR, simpleNamePattern) : CharOperation.concat(
					qualificationPattern, simpleNamePattern, '.');
		}
	}

	public PatternLocator(SearchPattern pattern) {
		int matchRule = pattern.getMatchRule();
		this.isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
		this.isCamelCase = (matchRule & SearchPattern.R_CAMELCASE_MATCH) != 0;
		this.isErasureMatch = (matchRule & SearchPattern.R_ERASURE_MATCH) != 0;
		this.isEquivalentMatch = (matchRule & SearchPattern.R_EQUIVALENT_MATCH) != 0;
		this.matchMode = matchRule & DLTKSearchPattern.MATCH_MODE_MASK;
	}

	/*
	 * Clear caches
	 */
	protected void clear() {
		// nothing to clear by default
	}

	/*
	 * (non-Javadoc) Modify PatternLocator.qualifiedPattern behavior: do not add
	 * star before simple name pattern when qualification pattern is null. This
	 * avoid to match p.X when pattern is only X...
	 */
	protected char[] getQualifiedPattern(char[] simpleNamePattern,
			char[] qualificationPattern) {
		// NOTE: if case insensitive search then simpleNamePattern &
		// qualificationPattern are assumed to be lowercase
		if (simpleNamePattern == null) {
			if (qualificationPattern == null)
				return null;
			return CharOperation.concat(qualificationPattern, ONE_STAR, '.');
		} else if (qualificationPattern == null) {
			return simpleNamePattern;
		} else {
			return CharOperation.concat(qualificationPattern,
					simpleNamePattern, '.');
		}
	}

	/**
	 * Initializes this search pattern so that polymorphic search can be
	 * performed.
	 */
	public void initializePolymorphicSearch(MatchLocator locator) {
		// default is to do nothing
	}

	public int match(Annotation node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	/**
	 * Check if the given ast node syntactically matches this pattern. If it
	 * does, add it to the match set. Returns the match level.
	 */
	public int match(ASTNode node, MatchingNodeSet nodeSet) { // needed for
		// some generic
		// nodes
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(CallExpression node, MatchingNodeSet nodeSet) { // needed
		// for
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(Expression node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(Reference node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(TypeReference node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
		// each subtype should override if needed
		return IMPOSSIBLE_MATCH;
	}

	/**
	 * Returns the type(s) of container for this pattern. It is a bit
	 * combination of types, denoting compilation unit, class declarations,
	 * field declarations or method declarations.
	 */
	public int matchContainer() {
		// override if the pattern can be more specific
		return ALL_CONTAINER;
	}

	/**
	 * Returns whether the given name matches the given pattern.
	 */
	protected boolean matchesName(char[] pattern, char[] name) {
		if (pattern == null)
			return true; // null is as if it was "*"
		if (name == null)
			return false; // cannot match null name
		return matchNameValue(pattern, name) != IMPOSSIBLE_MATCH;
	}

	/**
	 * Return how the given name matches the given pattern.
	 * 
	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866"
	 * 
	 * @param pattern
	 * @param name
	 * @return Possible values are:
	 *         <ul>
	 *         <li>{@link #POSSIBLE_FULL_MATCH}: Given name is equals to pattern
	 *         </li>
	 *         <li>{@link #POSSIBLE_PREFIX_MATCH}: Given name prefix equals to
	 *         pattern</li>
	 *         <li>{@link #POSSIBLE_CAMELCASE_MATCH}: Given name matches pattern
	 *         as Camel Case</li>
	 *         <li>{@link #POSSIBLE_PATTERN_MATCH}: Given name matches pattern
	 *         as Pattern (ie. using '*' and '?' characters)</li>
	 *         </ul>
	 */
	protected int matchNameValue(char[] pattern, char[] name) {
		if (pattern == null)
			return ACCURATE_MATCH; // null is as if it was "*"
		if (name == null)
			return IMPOSSIBLE_MATCH; // cannot match null name
		if (name.length == 0) { // empty name
			if (pattern.length == 0) { // can only matches empty pattern
				return ACCURATE_MATCH;
			}
			return IMPOSSIBLE_MATCH;
		} else if (pattern.length == 0) {
			return IMPOSSIBLE_MATCH; // need to have both name and pattern
			// length==0 to be accurate
		}
		boolean matchFirstChar = !this.isCaseSensitive || pattern[0] == name[0];
		boolean sameLength = pattern.length == name.length;
		boolean canBePrefix = name.length >= pattern.length;
		if (this.isCamelCase && matchFirstChar
				&& CharOperation.camelCaseMatch(pattern, name)) {
			return POSSIBLE_CAMELCASE_MATCH;
		}
		switch (this.matchMode) {
		case SearchPattern.R_EXACT_MATCH:
			if (!this.isCamelCase) {
				if (sameLength
						&& matchFirstChar
						&& CharOperation.equals(pattern, name,
								this.isCaseSensitive)) {
					return POSSIBLE_FULL_MATCH;
				}
				break;
			}
			// fall through next case to match as prefix if camel case
			// failed
		case SearchPattern.R_PREFIX_MATCH:
			if (canBePrefix
					&& matchFirstChar
					&& CharOperation.prefixEquals(pattern, name,
							this.isCaseSensitive)) {
				return POSSIBLE_PREFIX_MATCH;
			}
			break;
		case SearchPattern.R_PATTERN_MATCH:
			if (!this.isCaseSensitive) {
				pattern = CharOperation.toLowerCase(pattern);
			}
			if (CharOperation.match(pattern, name, this.isCaseSensitive)) {
				return POSSIBLE_MATCH;
			}
			break;
		case SearchPattern.R_REGEXP_MATCH:
			if (compiledPattern == null) {
				compiledPattern = Pattern.compile(new String(pattern),
						this.isCaseSensitive ? 0 : Pattern.CASE_INSENSITIVE);
			}
			if (compiledPattern.matcher(new String(name)).matches()) {
				return POSSIBLE_REGEXP_MATCH;
			}
			break;
		}
		return IMPOSSIBLE_MATCH;
	}

	/**
	 * Reports the match of the given reference.
	 */
	protected void matchReportReference(ASTNode reference,
			IModelElement element, int accuracy, MatchLocator locator)
			throws CoreException {
		match = null;
		switch (referenceType()) {
		case IModelElement.TYPE:
			match = locator.newTypeReferenceMatch(element, accuracy, reference
					.matchStart(), reference.matchLength(), reference);
			break;
		case IModelElement.FIELD:
			match = locator.newFieldReferenceMatch(element, accuracy, reference
					.matchStart(), reference.matchLength(), reference);
			break;
		case IModelElement.METHOD:
			match = locator.newMethodReferenceMatch(element, accuracy,
					reference.matchStart(), reference.matchLength(), false,
					false, reference);
			break;
		}
		if (match != null) {
			locator.report(match);
		}
	}

	/**
	 * Reports the match of the given reference. Also provide a local element to
	 * eventually report in match.
	 */
	protected void matchReportReference(ASTNode reference,
			IModelElement element, IModelElement localElement,
			IModelElement[] otherElements, int accuracy, MatchLocator locator)
			throws CoreException {
		matchReportReference(reference, element, accuracy, locator);
	}

	/**
	 * Reports the match of the given reference. Also provide a scope to look
	 * for potential other elements.
	 */
	public void matchReportReference(ASTNode reference, IModelElement element,
			Scope scope, int accuracy, MatchLocator locator)
			throws CoreException {
		matchReportReference(reference, element, accuracy, locator);
	}

	/**
	 * @deprecated
	 */
	@Deprecated
	public final SearchMatch newDeclarationMatch(ASTNode reference,
			IModelElement element, int accuracy, int length,
			MatchLocator locator) {
		return newDeclarationMatch(reference, element, accuracy, locator);
	}

	public SearchMatch newDeclarationMatch(ASTNode reference,
			IModelElement element, int accuracy, MatchLocator locator) {
		return locator.newDeclarationMatch(element, accuracy, reference
				.matchStart(), reference.matchLength());
	}

	protected int referenceType() {
		return 0; // defaults to unknown (a generic JavaSearchMatch will be
		// created)
	}

	/**
	 * Finds out whether the given ast node matches this search pattern. Returns
	 * IMPOSSIBLE_MATCH if it doesn't. Returns INACCURATE_MATCH if it
	 * potentially matches this search pattern (ie. it has already been resolved
	 * but resolving failed.) Returns ACCURATE_MATCH if it matches exactly this
	 * search pattern (ie. it doesn't need to be resolved or it has already been
	 * resolved.)
	 */
	public int resolveLevel(ASTNode possibleMatchingNode) {
		// only called with nodes which were possible matches to the call to
		// matchLevel
		// need to do instance of checks to find out exact type of ASTNode
		return IMPOSSIBLE_MATCH;
	}

	/*
	 * Update pattern locator match comparing type arguments with pattern ones.
	 * Try to resolve pattern and look for compatibility with type arguments to
	 * set match rule.
	 */
	protected void updateMatch(MatchLocator locator, char[][] patternArguments,
			boolean hasTypeParameters) {
		if (DLTKCore.DEBUG) {
			System.err.println("TODO: updateMatch"); //$NON-NLS-1$
		}
	}

	/**
	 * Returns whether the given type binding matches the given simple name
	 * pattern and qualification pattern. Note that this method resolve to
	 * accurate member or local types even if they are not fully qualified (ie.
	 * X.Member instead of p.X.Member). Returns ACCURATE_MATCH if it does.
	 * Returns INACCURATE_MATCH if resolve failed. Returns IMPOSSIBLE_MATCH if
	 * it doesn't.
	 */
	protected int resolveLevelForType(char[] simpleNamePattern,
			char[] qualificationPattern) {
		return INACCURATE_MATCH;
	}

	/**
	 * Returns whether the given type binding matches the given qualified
	 * pattern. Returns ACCURATE_MATCH if it does. Returns INACCURATE_MATCH if
	 * resolve failed. Returns IMPOSSIBLE_MATCH if it doesn't.
	 */
	protected int resolveLevelForType(char[] qualifiedPattern) {
		return IMPOSSIBLE_MATCH;
	}

	@Override
	public String toString() {
		return "SearchPattern"; //$NON-NLS-1$
	}
}
