/*******************************************************************************
 * Copyright (c) 2000, 2006 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
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.rename;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.Assert;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportContainer;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;


public class RefactoringScanner {
	
	private static int NO_MATCH= 0;
	private static int MATCH_QUALIFIED= 1;
	private static int MATCH_UNQUALIFIED= 2;

	public static class TextMatch {

		private int fStartPosition;
		private boolean fQualified;

		private TextMatch(int startPosition, boolean qualified) {
			fStartPosition= startPosition;
			fQualified= qualified;
		}

		public int getStartPosition() {
			return fStartPosition;
		}

		public boolean isQualified() {
			return fQualified;
		}
	}

	private final String fName;
	private final String fQualifier;
	
	private IScanner fScanner;
	private ISourceRange fNoFlyZone; // don't scan in ImportContainer (sometimes edited by ImportStructure)
	private Set fMatches; //Set<TextMatch>

	
	public RefactoringScanner(String name, String qualifier) {
		Assert.isNotNull(name);
		Assert.isNotNull(qualifier);
		fName= name;
		fQualifier= qualifier;
	}
	
	public void scan(ICompilationUnit cu)	throws JavaModelException {
		char[] chars= cu.getBuffer().getCharacters();
		fMatches= new HashSet();
		fScanner= ToolFactory.createScanner(true, true, false, true);
		fScanner.setSource(chars);

		IImportContainer importContainer= cu.getImportContainer();
		if (importContainer.exists())
			fNoFlyZone= importContainer.getSourceRange();
		else
			fNoFlyZone= null;
		
		doScan();
		fScanner= null;
	}

	/** only for testing */
	public void scan(String text) {
		char[] chars= text.toCharArray();
		fMatches= new HashSet();
		fScanner= ToolFactory.createScanner(true, true, false, true);
		fScanner.setSource(chars);
		doScan();
		fScanner= null;
	}

	private void doScan() {
		try{
			int token = fScanner.getNextToken();
			while (token != ITerminalSymbols.TokenNameEOF) {
				switch (token) {
					case ITerminalSymbols.TokenNameStringLiteral :
					case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
					case ITerminalSymbols.TokenNameCOMMENT_LINE :
					case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
						parseCurrentToken();
				}
				token = fScanner.getNextToken();
			}
		} catch (InvalidInputException e){
			//ignore
		}	
	}

	private static boolean isWholeWord(String value, int from, int to){
		if (from > 0) {
			char ch= value.charAt(from - 1);
			if (Character.isLetterOrDigit(ch) || ch == '_') {
				return false;
			}
		}
		if (to < value.length()) {
			char ch= value.charAt(to);
			if (Character.isLetterOrDigit(ch) || ch == '_' ) {
				return false;
			}
		}
		return true;
	}
	
	private void parseCurrentToken() {
		// only works for references without whitespace
		String value = new String(fScanner.getRawTokenSource());
		int start= fScanner.getCurrentTokenStartPosition();
		int index= value.indexOf(fName);
		while (index != -1) {
			if (isWholeWord(value, index, index + fName.length())) {
				int ok= isQualifierOK(value, index);
				if (ok > NO_MATCH)
					addMatch(start + index, ok);
			}
			index= value.indexOf(fName, index + 1);
		}
	}

	private int isQualifierOK(String value, int nameStart) {
		// only works for references without whitespace
		int qualifierAfter= nameStart - 1;
		if (qualifierAfter < 0)
			// there is absolutely nothing before the name itself in the string
			return MATCH_UNQUALIFIED;
		
		char charBeforeName= value.charAt(qualifierAfter);
		if (! isQualifierSeparator(charBeforeName))
			// the char before the name is not a # or . - should not get here anyway
			return MATCH_UNQUALIFIED; // NO_MATCH ?
		
		boolean canFinish= charBeforeName == '#';
		// work through the qualifier from back to front
		for (int i= 0; i < fQualifier.length() ; i++) {
			int qualifierCharPos= qualifierAfter - 1 - i;
			if (qualifierCharPos < 0)
				// the position does not exist, return OK if last read char was a non-separator
				return canFinish ? MATCH_UNQUALIFIED : NO_MATCH;
			
			char qualifierChar= value.charAt(qualifierCharPos);
			char goalQualifierChar= fQualifier.charAt(fQualifier.length() - 1 - i);
			if (qualifierChar != goalQualifierChar)
				// the chars do not match. return OK if last read char was a non-separator and the current one a non-qualifier
				return (canFinish && !isQualifierPart(qualifierChar)) ? MATCH_UNQUALIFIED : NO_MATCH;
			
			canFinish= ! isQualifierSeparator(qualifierChar);
		}
		int beforeQualifierPos= qualifierAfter - fQualifier.length() - 1;
		if (beforeQualifierPos >= 0) {
			char beforeQualifierChar= value.charAt(beforeQualifierPos);
			boolean charBeforeQualifierIsQualifierPart= isQualifierPart(beforeQualifierChar);
			// true if the char before the qualifier is a normal letter
			// (and therefore invalidates the whole string)
			return charBeforeQualifierIsQualifierPart ? NO_MATCH : MATCH_QUALIFIED;
		}
		return MATCH_QUALIFIED;
	}

	private boolean isQualifierPart(char ch) {
		return Character.isJavaIdentifierPart(ch) || isQualifierSeparator(ch);
	}

	private boolean isQualifierSeparator(char c) {
		return ".#".indexOf(c) != -1; //$NON-NLS-1$
	}

	private void addMatch(int matchStart, int matchCode) {
		if (fNoFlyZone != null 
				&& fNoFlyZone.getOffset() <= matchStart
				&& matchStart < fNoFlyZone.getOffset() + fNoFlyZone.getLength())
			return;
		fMatches.add(new TextMatch(matchStart, matchCode == MATCH_QUALIFIED));		
	}

	/**
	 * @return Set of TextMatch
	 */
	public Set getMatches() {
		return fMatches;
	}
}

