/*******************************************************************************
 * Copyright (c) 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.cdt.errorparsers.xlc;

import java.util.StringTokenizer;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IErrorParser;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.core.resources.IFile;

/**
 * This class provides methods for parsing the error messages
 * generated by xlc compiler.
 * @author ravisankar
 *
 */
public class XlcErrorParser implements IErrorParser 
{
	private String fileName;
	private int lineNumber;
	private String severity;
	private String message;
	private int severityNum;
	public XlcErrorParser()
	{
		fileName = null;
		lineNumber = -1;
		severity = null;
		message = null;
		severityNum = -1;
	}
	/**
	 * This function returns the file name extracted from
	 * the error message.
	 * @return The string value of the given file name.
	 */
	public String getFileName()
	{
		return fileName;
	}
	/**
	 * This function returns the line number of
	 * the error.
	 * @return The integer value of the line number.
	 */
	public int getLineNumber()
	{
		return lineNumber;
	}
	/**
	 * This function returns the severity of the
	 * error that has occured.
	 * @return The string value of the severity.
	 */
	public String getSeverity()
	{
		return severity;
	}
	/**
	 * This function returns the descriptive string of the
	 * error that has occured.
	 * @return The string value of the message.
	 */
	public String getMessage()
	{
		return message;
	}
	/**
	 * This function parses the error message occured and fills the
	 * class variables fileName, lineNumber, message, severity.
	 * @param line is the error message generated by the xlC compiler. 
	 * @return a boolean value indicating the success/failure of 
	 * extracting the values for fileName, lineNumber, message, severity. 
	 */
	public boolean parseLine(String line)
	{
		String lineNum = null;
		String secondPart = null;
		StringTokenizer tok = null;
		int firstComma = line.indexOf(',');  //$NON-NLS-1$
		// Check for the first occurance of comma.
		if( firstComma != -1 )
		{
			String firstPart = line.substring(0,firstComma);
			/* Check for double-quotes before the first occurance
			 of comma. */
			tok = new StringTokenizer(firstPart,"\""); //$NON-NLS-1$
			if(tok.hasMoreTokens())
			{
				fileName = tok.nextToken();
			}
			else
			{
				/* If the file name doesnot exist return
				 false. */
				return false;
			}
			secondPart = line.substring(firstComma + 1);
			/* look for '.' character after the first occurance
			   of comma. */
			tok = new StringTokenizer(secondPart,".");  //$NON-NLS-1$
			if(tok.hasMoreTokens())
			{
				String token = tok.nextToken();
				/* look for the string  "line " before the
				   the occurance of '.' operator. */ 
				int index;
				if( (index = token.indexOf("line ")) != -1) //$NON-NLS-1$
				{
					/* The string that begins after "line " and ends
					   before '.' operator is the line number. */
					lineNum = token.substring(index + 5);
					lineNumber = Integer.parseInt(lineNum);
				}
				else
				{
					return false;
				}
			}
			int index = -1;
			/* look for the first occurance of ")" after the
			 * first occurance of comma. 
			 */
			index = secondPart.indexOf(")"); //$NON-NLS-1$
			if( -1 == index )
			{
				return false;
			}
			/* The character that resides before the ")" operator
			 * indicates the severity of the message. The part of the
			 * error message that follows ")" is the description of the 
			 * error. 
			 */
			message = secondPart.substring(index + 1);
			severity = secondPart.substring(index - 1, index);
			if( severity.equals("I") ) //$NON-NLS-1$
			{
				severityNum = IMarkerGenerator.SEVERITY_INFO;
			}
			else if( severity.equals("W") ) //$NON-NLS-1$
			{
				severityNum = IMarkerGenerator.SEVERITY_WARNING;
			}
			else if( severity.equals("E") || severity.equals("S") ) //$NON-NLS-1$ //$NON-NLS-2$
			{
				severityNum = IMarkerGenerator.SEVERITY_ERROR_RESOURCE;
			}
			else if( severity.equals("U") ) //$NON-NLS-1$
			{
				severityNum = IMarkerGenerator.SEVERITY_ERROR_BUILD;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
		return true;
	}
	/**
	 * This function processes the error message and passed the information
	 * to the ErrorParserManager.  
	 * @param line is the error message generated by the xlc compiler
	 * and eoParser is the ErrorParserManager object.
	 * @return a boolean value indicating the success/failure of 
	 * extracing values from the error message.
	 */
	public boolean processLine(String line, ErrorParserManager eoParser) 
	{
		try 
		{
			if( parseLine(line) )
			{
				IFile file = null;
				if (fileName != null) 
				{
					file = eoParser.findFileName(fileName);
					if (file != null) 
					{
						/* Check if there are conflicting file
						 * names.
						 */
						if (eoParser.isConflictingName(fileName)) 
						{
							file = null;
						}
					} 
					else 
					{
						// Find the path of the file. 
						file = eoParser.findFilePath(fileName);
					}
					if (file == null) 
					{
						message = fileName + " " + message; //$NON-NLS-1$ 
					}
				}
				eoParser.generateMarker(file, lineNumber, message, severityNum, null);
				return true;
			}
			else
			{
				return false;
			}
		}
		catch(NumberFormatException e )
		{
			throw e;
		}
	}
}