/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.util.Util;

public class PackageReferenceLocator extends PatternLocator {

protected PackageReferencePattern pattern;

// check that referenced type is actually defined in this package fragment
public static boolean isDeclaringPackageFragment(IPackageFragment packageFragment, ReferenceBinding typeBinding) {
	char[] fileName = typeBinding.getFileName();
	if (fileName != null) {
		// retrieve the actual file name from the full path (sources are generally only containing it already)
		CharOperation.replace(fileName, '/', '\\');
		fileName = CharOperation.lastSegment(fileName, '\\');
		
		try { 
			switch (packageFragment.getKind()) {
				case IPackageFragmentRoot.K_SOURCE :
					if (!Util.isJavaFileName(fileName) || !packageFragment.getCompilationUnit(new String(fileName)).exists()) {
						return false; // unit doesn't live in selected package
					}
					break;
				case IPackageFragmentRoot.K_BINARY :
//					if (Util.isJavaFileName(fileName)) { // binary with attached source
//						int length = fileName.length;
//						System.arraycopy(fileName, 0, fileName = new char[length], 0, length - 4); // copy all but extension
//						System.arraycopy(SuffixConstants.SUFFIX_class, 0, fileName, length - 4, 4);
//					}
					if (!Util.isClassFileName(fileName) || !packageFragment.getClassFile(new String(fileName)).exists()) {
						return false; // classfile doesn't live in selected package
					}
					break;
			}
		} catch(JavaModelException e) {
			// unable to determine kind; tolerate this match
		}
	}
	return true; // by default, do not eliminate 
}

public PackageReferenceLocator(PackageReferencePattern pattern) {
	super(pattern);

	this.pattern = pattern;
}
public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ImportReference
	if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH;

	return nodeSet.addMatch(node, matchLevel((ImportReference) node));
}
//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
public int match(Reference node, MatchingNodeSet nodeSet) { // interested in QualifiedNameReference
	if (!(node instanceof QualifiedNameReference)) return IMPOSSIBLE_MATCH;

	return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedNameReference) node).tokens));
}
//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
public int match(TypeReference node, MatchingNodeSet nodeSet) { // interested in QualifiedTypeReference only
	if (!(node instanceof QualifiedTypeReference)) return IMPOSSIBLE_MATCH;

	return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedTypeReference) node).tokens));
}

protected int matchLevel(ImportReference importRef) {
	if (!importRef.onDemand)
		return matchLevelForTokens(importRef.tokens);

	return matchesName(this.pattern.pkgName, CharOperation.concatWith(importRef.tokens, '.'))
		? ACCURATE_MATCH
		: IMPOSSIBLE_MATCH;
}
protected int matchLevelForTokens(char[][] tokens) {
	if (this.pattern.pkgName == null) return ACCURATE_MATCH;

	switch (this.matchMode) {
		case SearchPattern.R_EXACT_MATCH:
		case SearchPattern.R_PREFIX_MATCH:
			if (CharOperation.prefixEquals(this.pattern.pkgName, CharOperation.concatWith(tokens, '.'), this.isCaseSensitive))
				return POSSIBLE_MATCH;
			break;
		case SearchPattern.R_PATTERN_MATCH:
			char[] patternName = this.pattern.pkgName[this.pattern.pkgName.length - 1] == '*'
				? this.pattern.pkgName
				: CharOperation.concat(this.pattern.pkgName, ".*".toCharArray()); //$NON-NLS-1$
			if (CharOperation.match(patternName, CharOperation.concatWith(tokens, '.'), this.isCaseSensitive))
				return POSSIBLE_MATCH;
			break;
	}
	return IMPOSSIBLE_MATCH;
}
protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
	if (binding == null) {
		this.matchReportReference(importRef, element, accuracy, locator);
	} else {
		if (locator.encloses(element)) {
			long[] positions = importRef.sourcePositions;
			int last = positions.length - 1;
			if (binding instanceof ProblemReferenceBinding)
				binding = ((ProblemReferenceBinding) binding).original;
			if (binding instanceof ReferenceBinding) {
				PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage;
				if (pkgBinding != null)
					last = pkgBinding.compoundName.length;
			}
			int start = (int) (positions[0] >>> 32);
			int end = (int) positions[last - 1];
			SearchMatch match = locator.newPackageReferenceMatch(element, accuracy, start, end-start+1, importRef);
			locator.report(match);
		}
	}
}
protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
	long[] positions = null;
	int last = -1;
	if (reference instanceof ImportReference) {
		ImportReference importRef = (ImportReference) reference;
		positions = importRef.sourcePositions;
		last = importRef.onDemand ? positions.length : positions.length - 1;
	} else {
		TypeBinding typeBinding = null;
		if (reference instanceof QualifiedNameReference) {
			QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
			positions = qNameRef.sourcePositions;
			switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
				case BindingIds.FIELD : // reading a field
					typeBinding = qNameRef.actualReceiverType;
					break;
				case BindingIds.TYPE : //=============only type ==============
					if (qNameRef.binding instanceof TypeBinding)
						typeBinding = (TypeBinding) qNameRef.binding;
					break;
				case BindingIds.VARIABLE : //============unbound cases===========
				case BindingIds.TYPE | BindingIds.VARIABLE :
					Binding binding = qNameRef.binding; 
					if (binding instanceof TypeBinding) {
						typeBinding = (TypeBinding) binding;
					} else if (binding instanceof ProblemFieldBinding) {
						typeBinding = qNameRef.actualReceiverType;
						last = qNameRef.tokens.length - (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2);
					} else if (binding instanceof ProblemBinding) {
						ProblemBinding pbBinding = (ProblemBinding) binding;
						typeBinding = pbBinding.searchType;
						last = CharOperation.occurencesOf('.', pbBinding.name);
					}
					break;					
			}
		} else if (reference instanceof QualifiedTypeReference) {
			QualifiedTypeReference qTypeRef = (QualifiedTypeReference) reference;
			positions = qTypeRef.sourcePositions;
			typeBinding = qTypeRef.resolvedType;
		}
		if (typeBinding instanceof ArrayBinding)
			typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
		if (typeBinding instanceof ProblemReferenceBinding)
			typeBinding = ((ProblemReferenceBinding) typeBinding).original;
		if (typeBinding instanceof ReferenceBinding) {
			PackageBinding pkgBinding = ((ReferenceBinding) typeBinding).fPackage;
			if (pkgBinding != null)
				last = pkgBinding.compoundName.length;
		}
	}
	if (last == -1) {
		last = this.pattern.segments.length;
		if (last > positions.length) last = positions.length;
	}
	int sourceStart = (int) (positions[0] >>> 32);
	int sourceEnd = ((int) positions[last - 1]);
	SearchMatch match = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference);
	locator.report(match);
}
protected int referenceType() {
	return IJavaElement.PACKAGE_FRAGMENT;
}
public int resolveLevel(ASTNode node) {
	if (node instanceof QualifiedTypeReference)
		return resolveLevel(((QualifiedTypeReference) node).resolvedType);
	if (node instanceof QualifiedNameReference)
		return this.resolveLevel((QualifiedNameReference) node);
//	if (node instanceof ImportReference) - Not called when resolve is true, see MatchingNodeSet.reportMatching(unit)
	return IMPOSSIBLE_MATCH;
}
public int resolveLevel(Binding binding) {
	if (binding == null) return INACCURATE_MATCH;

	char[][] compoundName = null;
	if (binding instanceof ImportBinding) {
		compoundName = ((ImportBinding) binding).compoundName;
	} else {
		if (binding instanceof ArrayBinding)
			binding = ((ArrayBinding) binding).leafComponentType;
		if (binding instanceof ProblemReferenceBinding)
			binding = ((ProblemReferenceBinding) binding).original;
		if (binding == null) return INACCURATE_MATCH;

		if (binding instanceof ReferenceBinding) {
			PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage;
			if (pkgBinding == null) return INACCURATE_MATCH;
			compoundName = pkgBinding.compoundName;
		}
	}
	if (compoundName != null && matchesName(this.pattern.pkgName, CharOperation.concatWith(compoundName, '.'))) {
		if (((InternalSearchPattern) this.pattern).focus instanceof IPackageFragment && binding instanceof ReferenceBinding) {
			// check that type is located inside this instance of a package fragment
			if (!isDeclaringPackageFragment((IPackageFragment)((InternalSearchPattern) this.pattern).focus, (ReferenceBinding)binding)) return IMPOSSIBLE_MATCH;
		}				
		return ACCURATE_MATCH;
	} else {
		return IMPOSSIBLE_MATCH;
	}
}
protected int resolveLevel(QualifiedNameReference qNameRef) {
	TypeBinding typeBinding = null;
	switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
		case BindingIds.FIELD : // reading a field
			if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3))
				return IMPOSSIBLE_MATCH; // must be at least p1.A.x
			typeBinding = qNameRef.actualReceiverType;
			break;
		case BindingIds.LOCAL : // reading a local variable
			return IMPOSSIBLE_MATCH; // no package match in it
		case BindingIds.TYPE : //=============only type ==============
			if (qNameRef.binding instanceof TypeBinding)
				typeBinding = (TypeBinding) qNameRef.binding;
			break;
		/*
		 * Handling of unbound qualified name references. The match may reside in the resolved fragment,
		 * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
		 */
		case BindingIds.VARIABLE : //============unbound cases===========
		case BindingIds.TYPE | BindingIds.VARIABLE :
			Binding binding = qNameRef.binding; 
			if (binding instanceof ProblemReferenceBinding) {
				typeBinding = (TypeBinding) binding;
			} else if (binding instanceof ProblemFieldBinding) {
				if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3))
					return IMPOSSIBLE_MATCH; // must be at least p1.A.x
				typeBinding = qNameRef.actualReceiverType;
			} else if (binding instanceof ProblemBinding) {
				ProblemBinding pbBinding = (ProblemBinding) binding;
				if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
					return INACCURATE_MATCH;
				typeBinding = pbBinding.searchType;
			}
			break;					
	}
	return resolveLevel(typeBinding);
}
public String toString() {
	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
}
}
