package org.eclipse.ganymede.webgen;

import java.io.PrintWriter;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogLine {
	public String line;

	public int linenumber;

	public Status status;

	public Blame blame;

	String anchor;

	private static int nextanchor = 1;

	public LogLine(String s, int number) {
		this.linenumber = number;
		this.line = s;
		this.status = Status.unknown;
	}

	public String addAnchor() {
		this.anchor = "" + nextanchor++;
		return this.anchor;
	}

	public String getAnchor() {
		return this.anchor;
	}
	public Blame getBlame() {
		return this.blame;
	}

	public void write_log_line(PrintWriter writer) {
		if (status.isFail()) {
			writer.print("<span style=\"background-color: "
					+ WebPageColors.fail_color() + ";\">");
		}
		if (status.isSuccess()) {
			writer.print("<span style=\"background-color: "
					+ WebPageColors.success_color() + ";\">");
		}
		writer.print("<code>");
		if (this.anchor != null) {
			writer.print("<a name=\"" + this.anchor + "\"></a>");
		}
		writer.print(line);
		writer.print("</code>");
		if (status.isFail() || status.isSuccess()) {
			writer.print("</span>");
		}
	}

	private static Pattern pGood = Pattern.compile("(^BUILD SUCCESSFUL)"
			+ "|(\\s*\\[java\\]\\s*(INFO:\\s*)?Import complete)");
	private static Pattern pBad = Pattern.compile("([Ee]xception)"
			+ "|([Ee]rror)" + "|([Ff]ail)"
			+ "|(^verify\\.properties\\.error:$)");
	private static String sSpecialCasesForPlatform = 
		  "|(ContinueOnError: The following ID was not found, so was skipped, and is not on mir+or site: .*(org\\.eclipse\\.swt\\.gtk|org\\.eclipse\\.equinox\\.launcher\\.gtk))"
		+ "|(ContinueOnError: The following ID was not found, so was skipped, and is not on mir+or site: .*(org\\.eclipse\\.swt\\.win32\\.win32\\.ia64|org\\.eclipse\\.equinox\\.launcher\\.win32\\.win32\\.ia64|org\\.eclipse\\.core\\.filesystem\\.win32\\.ia64|org\\.eclipse\\.core\\.resources\\.win32\\.ia64))"
		+ "|(\\s*\\[java\\]\\s*java.lang.UnsatisfiedLinkError: localfile_1_0_0)"
		;
	private static Pattern pNotBad = Pattern.compile("('--continueonerror')"
			+ "|(so this may not be an error)"
			+ "|(Workspace was not properly initialized or has already shutdown)"
			+ sSpecialCasesForPlatform
			);
	private static Pattern pOk = Pattern
			.compile(""
					+ "(^Buildfile: .*$)"
					+ "|(^generate.bm.artifacts:)"
					+ "|(^\\s*\\[mkdir\\] Created dir: )"
					+ "|(^\\s*\\[delete\\] Deleting directory )"
					+ "|(^\\s*\\[echo\\]\\s*\".*\\.sc\")"
					+ "|(^\\s*\\[java\\]\\s*Creating directory )"
					+ "|(^\\s*\\[java\\]\\s*generate '--outputdir' )"
					+ "|(^\\s*\\[java\\]\\s*Generating artifacts from file:)"
					+ "|(^\\s*\\[java\\]\\s*Writing generated artifacts to )"
					+ "|(^\\s*\\[java\\]\\s*Platform install location: )"
					+ "|(^\\s*\\[java\\]\\s*Generation complete)"
					+ "|(^resolve.cquery:)"
					+ "|(\\s*\\[java\\]\\s*resolve '--continueonerror' )"
					+ "|(\\s*\\[java\\]\\s*Using workspace at )"
					+ "|(\\s*\\[java\\]\\s*Platform install location: )"
					+ "|(\\s*\\[java\\]\\s*Found searchPath default for component )"
					+ "|(\\s*\\[java\\]\\s*Provider url\\(.*\\): Found a match for component )"
					+ "|(\\s*\\[java\\]\\s*Found searchPath .*for component )"
					+ "|(\\s*\\[java\\]\\s*Provider site.feature(.*): Found a match for .* using version designator )"
					+ "|(\\s*\\[java\\]\\s*Query complete.)"
					+ "|(\\s*\\[java\\]\\s*(INFO:\\s*)?Could not load library: .*This library provides platform-specific optimizations for certain file system operations.  This library is not present on all platforms, so this may not be an error.  )"
					+ "|(\\s*\\[java\\]\\s*java.lang.UnsatisfiedLinkError: localfile_1_0_0)"
					+ "|(\\s*\\[java\\]\\s*at )" //too bad we have to 'ok' this, because this is really a stack dump and it should be an error
												 //but this log line parser isn't clever enough to know that stack dumps following the localfile_1_0_0 line
												 //are _not_ errors whereas all the rest of the stack dumps _are_ errors.
					+ "|(^materialize:)"
					+ "|(Workspace was not properly initialized or has already shutdown)"
					+ "|(\\s*\\[java\\]\\s*import )"
					+ "|(\\s*\\[java\\]\\s*Using workspace at )"
					+ "|(\\s*\\[java\\]\\s*Platform install location: )"
					+ "|(\\s*\\[java\\]\\s*Installing features finished. Updating categories )"
					+ "|(\\s*\\[java\\]\\s*Updating categories finished. Updating site description )"
					+ "|(\\s*\\[java\\]\\s*Updating site description finished. Saving site.xml )"
					+ "|(\\s*\\[java\\]\\s*Mirroring feature )"
					+ "|(\\s*\\[java\\]\\s*Getting plugin entries for )"
					+ "|(\\s*\\[java\\]\\s*Getting non plugin entries for )"
					+ "|(\\s*\\[java\\]\\s*Getting included features for )"
					+ "|(\\s*\\[java\\]\\s*Downloading feature archives for )"
					+ "|(\\s*\\[java\\]\\s*Downloading plug-in archives for )"
					+ "|(\\s*\\[java\\]\\s*Downloading non plug-in archives for )"
					+ "|(\\s*\\[java\\]\\s*Installing child features for )"
					+ "|(\\s*\\[java\\]\\s*Storing plug-in archives for )"
					+ "|(\\s*\\[java\\]\\s*Storing non plug-in archives for )"
					+ "|(\\s*\\[java\\]\\s*Storing feature archives for )"
					+ "|(\\s*\\[java\\]\\s*Adding feature )"
					+ "|(\\s*\\[java\\]\\s*Feature .* added to site.xml)"
					+ "|(\\s*\\[java\\]\\s*Feature .* already exists\\.\\s*Skipping downloading\\.)"
					+ "|(\\s*\\[java\\]\\s*(INFO:?\\s*)?TAG-ID \\d+ =)"
					+ "|(\\s*\\[java\\]\\s*INFO:?\\s+)"
					+ "|(^\\s*\\[java\\]\\s*$)"
					+ "|(^\\s+\\[copy\\]\\s*Copying\\s+\\d+\\s+file)"
					+ "|(^Total time: \\d+)" + "|(^get\\.properties:$)"
					+ "|(^verify\\.properties\\..*:$)" + "|(^\\s*$)"
					
					/*
					 * Special case errors
					 */
					+ "|(\\s*\\[java\\]\\s*(ERROR:\\s*)?Digest could not be parsed:Unable to retrieve remote reference)"
					+ "|(\\s*\\[java\\]\\s*(ERROR:\\s*)?Digest could not be parsed:Element type \"includes\" must be followed by either attribute specifications)"
					+ sSpecialCasesForPlatform
					);

	public Status scan_for_status() {
		Matcher mBad = pBad.matcher(this.line);
		if (mBad.find()) {
			Matcher mNotBad = pNotBad.matcher(this.line);
			if (!mNotBad.find()) {
				this.status = Status.getFail();
				this.status.setErrorBookmark(this.addAnchor());
				this.status.setBlame(this.blame);
				return this.status;
			}
		}
		Matcher mGood = pGood.matcher(this.line);
		if (mGood.find()) {
			this.status = Status.success;
		} else {
			Matcher mOk = pOk.matcher(this.line);
			if (!mOk.find()) {
				this.status = Status.getFail();
				this.status.setErrorBookmark(this.addAnchor());
				this.status.setBlame(this.blame);
				return this.status;
			}
		}
		return this.status;
	}

	private static final Pattern pNeedBlame = Pattern
			.compile("(^\\s*\\[java\\]\\s+(?:ERROR\\s+)?\\[(\\d+)\\] :)"
					+ "|(^\\s*\\[java\\]\\s+(?:WARNING\\s+)?\\[(\\d+)\\] :)");

	public void assignBlameIfNeeded(Map<String, Blame> blames) {
		Matcher m = pNeedBlame.matcher(this.line);
		if (m.find()) {
			if( m.group(2) != null )
				this.blame = blames.get(m.group(2));
			if( m.group(4) != null )
				this.blame = blames.get(m.group(4));
		}
	}

	private static final Pattern pTAGID = Pattern
			.compile("^\\s*\\[java\\]\\s+(?:INFO:?\\s+)?TAG-ID (\\d+) = project: (\\S+),");

	public Blame parseBlame() {
		Matcher m = pTAGID.matcher(this.line);
		if (m.find())
			return new Blame(m.group(1), m.group(2));
		else
			return null;
	}
}
