package org.eclipse.jdt.internal.debug.ui.actions;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

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;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;

public class BreakpointLocationVerifier {

	/**
	 * Returns the line number closest to the given line number that represents a
	 * valid location for a breakpoint in the given document, or -1 if a valid location
	 * cannot be found.
	 */
	public int getValidBreakpointLocation(IDocument doc, int lineNumber) {

		IScanner scanner = ToolFactory.createScanner(false, false, false, false);
		boolean found = false;
		int start = 0, length = 0, token = 0, lastToken = 0;

		while (!found) {
			try {
				start = doc.getLineOffset(lineNumber);
				length = doc.getLineLength(lineNumber);
				char[] txt = doc.get(start, length).toCharArray();
				scanner.setSource(txt);
				token = scanner.getNextToken();
				if (token == ITerminalSymbols.TokenNameEQUAL) {
					break;
				}
				lastToken = 0;

				while (token != ITerminalSymbols.TokenNameEOF) {
					if (token == ITerminalSymbols.TokenNameERROR) {
						lineNumber++;
						break;
					}
					if (token == ITerminalSymbols.TokenNameIdentifier) {
						if (lastToken == ITerminalSymbols.TokenNameIdentifier
							|| isPrimitiveTypeToken(lastToken)
							|| lastToken == ITerminalSymbols.TokenNameRBRACKET) {
							//var declaration..is there initialization 
							//OR method parameters on a line all by themselves
							lastToken = token;
							token = scanner.getNextToken();
							if (token == ITerminalSymbols.TokenNameEQUAL) {
								found = true;
								break;
							}
						}
						if (lastToken == ITerminalSymbols.TokenNameMULTIPLY) {
							//internal comment line starting with '*'
							break;
						}
					} else if (isNonIdentifierValidToken(token)) {
						found = true;
						break;
					} else if (
						lastToken == ITerminalSymbols.TokenNameIdentifier
							&& token != ITerminalSymbols.TokenNameLBRACKET) {
						found = true;
						break;
					} else if (
						lastToken == ITerminalSymbols.TokenNameLBRACKET
							&& token == ITerminalSymbols.TokenNameRBRACKET) {
						//var declaration..is there initialization
						lastToken = token;
						token = scanner.getNextToken();
						if (token == ITerminalSymbols.TokenNameSEMICOLON) {
							//no init
							break;
						} else if (token == ITerminalSymbols.TokenNameEQUAL) {
							found = true;
							break;
						}

						continue;
					}

					lastToken = token;
					token = scanner.getNextToken();
				}
				if (!found) {
					lineNumber++;
				}
			} catch (BadLocationException ble) {
				return -1;
			} catch (InvalidInputException ie) {
				//start of a comment "/**" or "/*"
				lineNumber++;
			}
		}
		// add 1 to the line number - Document is 0 based, JDI is 1 based
		return lineNumber + 1;
	}

	protected boolean isPrimitiveTypeToken(int token) {
		switch (token) {
			case ITerminalSymbols.TokenNameboolean :
			case ITerminalSymbols.TokenNamebyte :
			case ITerminalSymbols.TokenNamechar :
			case ITerminalSymbols.TokenNamedouble :
			case ITerminalSymbols.TokenNamefloat :
			case ITerminalSymbols.TokenNameint :
			case ITerminalSymbols.TokenNamelong :
			case ITerminalSymbols.TokenNameshort :
				return true;
			default :
				return false;
		}
	}

	protected boolean isNonIdentifierValidToken(int token) {
		switch (token) {
			case ITerminalSymbols.TokenNamebreak :
			case ITerminalSymbols.TokenNamecontinue :
			case ITerminalSymbols.TokenNamereturn :
			case ITerminalSymbols.TokenNamethis :
			case ITerminalSymbols.TokenNamesuper :
				return true;
			default :
				return false;
		}
	}
}