package org.eclipse.ant.internal.ui;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import java.util.*;
import org.apache.tools.ant.*;
import org.eclipse.ant.core.AntRunner;import org.eclipse.ant.core.EclipseProject;
import org.eclipse.ant.core.IAntRunnerListener;import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.swt.widgets.Display;

// TBD
// * Marker mechanism doesn't work for Locations other than
//   the original build file. This could pose problems for
//   ant tasks.
// * incremental task shows minimal feedback

public class UIBuildListener implements IAntRunnerListener {
	
	private AntRunner runner;
	private IProgressMonitor fMonitor;
	private Target fTarget;
	private Task fTask;
	private IFile fBuildFile;
	private int msgOutputLevel = Project.MSG_INFO;
	private AntConsole[] consoles;
	private int logLength = 0;
	// index of the last target end
	private int lastTargetEndIndex = 0;
	private boolean isTargetWithDependencies = false;


public UIBuildListener(AntRunner runner, IProgressMonitor monitor, IFile file, AntConsole[] consoles) {
	super();
	this.consoles = consoles;
	this.runner = runner;
	fMonitor = monitor;
	fBuildFile = file;
	if (consoles != null)
    	for (int i=0; i < consoles.length; i++) {
			consoles[i].initializeOutputStructure();
			consoles[i].initializeTreeInput();
    	}
}
/**
 * @deprecated
 */
public UIBuildListener(AntRunner runner, IProgressMonitor monitor, IFile file) {
	super();
	
	this.runner = runner;
	fMonitor = monitor;
	fBuildFile = file;
}

public void buildFinished(BuildEvent be){
	fMonitor.done();
	if (be.getException() != null)
		handleBuildException(be.getException());
	
	// We must give the name of the project here because when the build starts, the name has not been parsed yet.
	setProjectNameForOutputStructures(be.getProject().getName());
	
	// and we finish the curent element
	finishCurrentOutputStructureElement();
	
	// And finaly tell the consoles to update
	refreshConsoleTrees();
}

private void setProjectNameForOutputStructures(String name) {
	if (consoles != null)
		for (int i=0; i < consoles.length; i++)
			consoles[i].currentElement.setName(name);
}

protected void refreshConsoleTrees() {
    if (consoles != null)
    	// create a new thread for synchronizing all the refresh operations
    	// we get the display from the console #0 (that exists for sure because consoles!=null)
    	consoles[0].getSite().getShell().getDisplay().syncExec(new Runnable() {
    		public void run() {
   				for (int i=0; i < consoles.length; i++)
					consoles[i].refreshTree();
    		}
    	});
}

public void buildStarted(BuildEvent be) {
	fMonitor.subTask(Policy.bind("monitor.buildStarted"));
	msgOutputLevel = runner.getOutputMessageLevel();
	removeMarkers();
	
	// the current (first) output element is the one for the script, so we have to set the end index for it
	finishCurrentOutputStructureElement();
	
	// we create the second element which represents the project.
	// Unfortunately, the name has not been parsed yet, so we'll have to catch it at the very end.
	// We give a default name ("Project") till we can actually set the real name.
	createNewOutputStructureElement(Policy.bind("console.project"));
}
private void checkCanceled() {
	if (fMonitor.isCanceled())
		throw new BuildCanceledException();
}
private void createMarker(IFile file, BuildException be) {
	try {
		int lineNumber= getLineFromLocation(be.getLocation());
		IMarker marker= file.createMarker(IMarker.PROBLEM);
		Map map= new HashMap();
		map.put(IMarker.LINE_NUMBER, new Integer(lineNumber));
		map.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
		map.put(IMarker.MESSAGE, be.getMessage());
		map.put(IMarker.LOCATION, Integer.toString(lineNumber));
		marker.setAttributes(map);
	} catch (CoreException e) {
		e.printStackTrace();
	}
}
private int getLineFromLocation(Location l) {
	String locstr= l.toString();
	int end= locstr.lastIndexOf(':');
	int start= locstr.lastIndexOf(':', end-1);
	String lstr= locstr.substring(start+1, end);
	try {
		return Integer.parseInt(lstr);
	} catch (NumberFormatException e) {
		return -1;
	}
}
private void handleBuildException(Throwable t) {
	logMessage(Policy.bind("exception.buildException", t.toString()) + "\n", Project.MSG_ERR);

	if (t instanceof BuildException) {
		BuildException bex= (BuildException)t;
		// the build exception has a location that
		// refers to a build file
		if (bex.getLocation() != Location.UNKNOWN_LOCATION)
			createMarker(fBuildFile, bex);
	}
}
public void messageLogged(BuildEvent event) {
	checkCanceled();
   	logMessage(event.getMessage() + "\n", event.getPriority());
}
public void messageLogged(String message,int priority) {
	checkCanceled();
   	logMessage(message + "\n", priority);
}
private void logMessage(String message, int priority) {
    if (consoles != null && priority <= msgOutputLevel) {
		for (int i=0; i < consoles.length; i++)
			consoles[i].append(message, priority);
		logLength += message.length();
    }
}
private void removeMarkers() {
	try {
		fBuildFile.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
	} catch (CoreException e) {
		e.printStackTrace();
	}
}
public void targetStarted(BuildEvent be) {
	checkCanceled();
	fTarget= be.getTarget();
	fMonitor.subTask(Policy.bind("monitor.targetColumn")+"\""+fTarget.getName()+"\" "+Policy.bind("monitor.started"));

	int startIndex = logLength;
	// the targets that need to look for the last target end index are targets that have no dependency and that
	// are in an EclipseProject (if they are in an standard Project, this means that they were executed with the 'ant'
	// task, and therefore have no ouput to look for)
	if (!isTargetWithDependencies && (be.getProject() instanceof EclipseProject))
		startIndex = lastTargetEndIndex;

	createNewOutputStructureElement(fTarget.getName(), startIndex);	
}
public void targetFinished(BuildEvent be) {
	checkCanceled();
	if (be.getException() != null)
		handleBuildException(be.getException());
	 
	//	one task is done: say it to the monitor
	fMonitor.worked(1);
	
	finishCurrentOutputStructureElement();
	
	// store the end index of this target's log (so that we can use it later)
	lastTargetEndIndex = logLength;
	
	refreshConsoleTrees();
}
public void executeTargetStarted(BuildEvent be){
	checkCanceled();
	fTarget= be.getTarget();
	fMonitor.subTask(Policy.bind("monitor.targetColumn")+"\""+fTarget.getName()+"\" "+Policy.bind("monitor.started"));
	
	// store the end index of the last target's log (so that we can use it later)
	// Usually, this is done at the #targetFinished, but when the first target is executed, no #targetFinished
	// has been triggered before so lastTargetEndIndex equals 0.
	lastTargetEndIndex = logLength;
	
	if (be.getTarget().getDependencies().hasMoreElements()) {
		// this target has dependencies
		// create a nested element for that purpose
		createNewOutputStructureElement(fTarget.getName(), logLength);
		isTargetWithDependencies = true;
	}
		
}
public void executeTargetFinished(BuildEvent be){
	checkCanceled();
	if (be.getException() != null)
		handleBuildException(be.getException());

	if (isTargetWithDependencies) {
		// we have the nested element to finish (the one that gathers all the target of the dependency)
		finishCurrentOutputStructureElement();
		isTargetWithDependencies = false;
	}
	
	refreshConsoleTrees();
}
public void taskStarted(BuildEvent be) {
	checkCanceled();
	fTask= be.getTask();
	fMonitor.subTask(Policy.bind("monitor.targetColumn")+"\""+fTarget.getName()+"\" - "+fTask.getTaskName());
	if (be.getException() != null)
		handleBuildException(be.getException());

	createNewOutputStructureElement(fTask.getTaskName());
}
public void taskFinished(BuildEvent be) {
	checkCanceled();
	
	finishCurrentOutputStructureElement();
	
	refreshConsoleTrees();
}

/*
 * Used to create output structure elements for targets.
 * 
 * Note: we need to have two different #createNewOutputStructureElement methods because
 * when we create a target, we need to take the two-last line index as the start index, not
 * the current index (this is because the Ant output is not well structured)
 */
protected void createNewOutputStructureElement(String name, int index) {
	if (consoles != null)
    	for (int i=0; i < consoles.length; i++) {
		    // creates a new OutputStructureElement with the current element as a parameter for the parent of this object
			OutputStructureElement newElement = new OutputStructureElement(name, consoles[i].currentElement, index);
			// and sets the current element to the one that has just been created
			consoles[i].currentElement = newElement;
    	}
}

/*
 * Used to create output structure elements for projects and tasks
 */
protected void createNewOutputStructureElement(String name) {
	createNewOutputStructureElement(name, logLength);
}

protected void finishCurrentOutputStructureElement() {
	if (consoles != null)
    	for (int i=0; i < consoles.length; i++) {
		    // sets the index that indicates the end of the log part linked to this element
			consoles[i].currentElement.setEndIndex(logLength);
			// and sets the current element to the parent of the element
			consoles[i].currentElement = consoles[i].currentElement.getParent();
    	}
}

}
