/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *     Matt Conway - Patch for Bug 28052
 *******************************************************************************/

package org.eclipse.ant.internal.launching.runtime.logger;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.eclipse.ant.internal.core.AbstractEclipseBuildLogger;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.launching.AntLaunch;
import org.eclipse.ant.internal.launching.AntLaunching;
import org.eclipse.ant.internal.launching.AntLaunchingUtil;
import org.eclipse.ant.internal.launching.debug.AntDebugState;
import org.eclipse.ant.internal.launching.launchConfigurations.AntProcess;
import org.eclipse.ant.internal.launching.launchConfigurations.AntStreamMonitor;
import org.eclipse.ant.internal.launching.launchConfigurations.AntStreamsProxy;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;

public class AntProcessBuildLogger extends NullBuildLogger {

	private long fStartTime;

	/**
	 * Associated process - discovered as needed to log messages
	 */
	private AntProcess fProcess = null;
	
	protected void logMessage(String message, BuildEvent event, int overridePriority) {
		int priority= overridePriority;
		if (priority == -1) {
			priority= event.getPriority();
		} 
		
		if (priority > getMessageOutputLevel()) {
			return;
		}
		AntProcess antProcess = getAntProcess(fProcessId);
		if (antProcess == null) {
			return;
		}
		
		StringBuffer fullMessage= new StringBuffer();
		 if (!loggingToLogFile()) {
			fullMessage.append(System.getProperty("line.separator")); //$NON-NLS-1$
		}
		if (event.getException() == null && event.getTask() != null && !fEmacsMode) {
			adornMessage(event, fullMessage);
		} else {
			fullMessage.append(message);
		}
		message= fullMessage.toString();
		
		if (loggingToLogFile()) {
			logMessageToLogFile(message, priority);
		} else {
			AntStreamMonitor monitor = getMonitor(priority);
			monitor.append(message);
		}
	}

	/**
	 * Builds a right justified task prefix for the given build event, placing it
	 * in the given string buffer. Creates the hyperlinks for the task prefix. 
	 *  
	 * @param event build event
	 * @param fullMessage buffer to place task prefix in
	 */
	private void adornMessage(BuildEvent event, StringBuffer fullMessage) {
		String name = event.getTask().getTaskName();
		if (name == null) {
			name = "null"; //$NON-NLS-1$
		}
		Location location = event.getTask().getLocation();
		StringBuffer column= new StringBuffer();
		int size = AntLaunching.LEFT_COLUMN_SIZE - (name.length() + 3);
		for (int i = 0; i < size; i++) {
			column.append(' ');
		}
		StringBuffer labelBuff= new StringBuffer();
		labelBuff.append('[');
		labelBuff.append(name);
		labelBuff.append("] "); //$NON-NLS-1$
		
		int offset = Math.max(size, 0) + 1;
		String label= labelBuff.toString();
		if (event.getMessage() == null) {
			return;
		}
		try {
			BufferedReader r = new BufferedReader(new StringReader(event.getMessage()));
			String line = r.readLine();
			fullMessage.append(column);
			appendAndLink(fullMessage, location, label, offset, line);
			line = r.readLine();
			while (line != null) {
				fullMessage.append(System.getProperty("line.separator")); //$NON-NLS-1$
				fullMessage.append(column);
				appendAndLink(fullMessage, location, label, offset, line);
				line = r.readLine();
			}
		} catch (IOException e) {
			if (event.getMessage() != null) {
				fullMessage.append(label).append(event.getMessage());
			}
		}
	}
	
	private void appendAndLink(StringBuffer fullMessage, Location location, String label, int offset, String line) {
		fullMessage.append(label);
		fullMessage.append(line);
		if (location != null) {
			String newLine= (label + line).trim();
			IRegion region= new Region(offset, label.length() - 3); // only
			// want
			// the
			// name
			// length
			// "[name] "
			AntProcess antProcess = getAntProcess(fProcessId);
			AntLaunch antLaunch = (AntLaunch)antProcess.getLaunch();
			antLaunch.addLinkDescriptor(newLine, location.getFileName(), location.getLineNumber(), region.getOffset(), region.getLength());
		}
	}

	private AntStreamMonitor getMonitor(int priority) {
		AntStreamsProxy proxy = (AntStreamsProxy)fProcess.getStreamsProxy();
		AntStreamMonitor monitor = null;
		switch (priority) {
			case Project.MSG_INFO:
				monitor = (AntStreamMonitor)proxy.getOutputStreamMonitor();
				break;
			case Project.MSG_ERR:
				monitor = (AntStreamMonitor)proxy.getErrorStreamMonitor();
				break;
			case Project.MSG_DEBUG:
				monitor = (AntStreamMonitor)proxy.getDebugStreamMonitor();
				break;
			case Project.MSG_WARN:
				monitor = (AntStreamMonitor)proxy.getWarningStreamMonitor();
				break;
			case Project.MSG_VERBOSE:
				monitor = (AntStreamMonitor)proxy.getVerboseStreamMonitor();
				break;
		}
		return monitor;
	}

	private void logMessageToLogFile(String message, int priority) {
		if (priority == Project.MSG_ERR) {
			getErrorPrintStream().println(message);
		} else {
			getOutputPrintStream().println(message);
		}
	}
	
	/**
	 * Returns the associated Ant process, finding it if necessary, if not
	 * already found.
	 */
	protected AntProcess getAntProcess(String processId) {
		if (fProcess == null && processId != null) {
			IProcess[] all = DebugPlugin.getDefault().getLaunchManager().getProcesses();
			for (int i = 0; i < all.length; i++) {
				IProcess process = all[i];
				if (process instanceof AntProcess && processId.equals(process.getAttribute(AbstractEclipseBuildLogger.ANT_PROCESS_ID))) {
					fProcess = (AntProcess)process;
					break;
				}
			}
		}
		return fProcess;
	}

	/* (non-Javadoc)
	 * Set the start time.
	 * 
	 * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent)
	 */
	public void buildStarted(BuildEvent event) {
		fStartTime= System.currentTimeMillis();
	}
	
	/* (non-Javadoc)
	 * @see org.apache.tools.ant.BuildListener#buildFinished(org.apache.tools.ant.BuildEvent)
	 */
	public void buildFinished(BuildEvent event) {
        String message= handleException(event);
        if (message != null) {
        	try {
    			BufferedReader r = new BufferedReader(new StringReader(message));
    			String line = r.readLine();
    			logMessage(line, event, Project.MSG_ERR);
    			line = r.readLine();
    			AntProcess antProcess = getAntProcess(fProcessId);
    			while (line != null) {
    				logMessage(line, event, Project.MSG_ERR);
    				if (!message.startsWith("Total time:")) { //$NON-NLS-1$
						AntLaunchingUtil.linkBuildFailedMessage(line, antProcess);
    				}
    				line = r.readLine();
    			}
    			logMessage(IAntCoreConstants.EMPTY_STRING, event, Project.MSG_ERR);
    		} catch (IOException e) {
    		}
        }
		fHandledException= null;
		if (!(event.getException() instanceof OperationCanceledException)) {
			logMessage(getTimeString(System.currentTimeMillis() - fStartTime), event, fMessageOutputLevel);
		}
		fProcess= null;
		event.getProject().removeBuildListener(this);
	}
	
	private String getTimeString(long milliseconds) {
			long seconds = milliseconds / 1000;
			long minutes = seconds / 60;
			seconds= seconds % 60;
		
			StringBuffer result= new StringBuffer(RuntimeMessages.AntProcessBuildLogger_Total_time);
			if (minutes > 0) {
				result.append(minutes);
				if (minutes > 1) {
					result.append(RuntimeMessages.AntProcessBuildLogger__minutes_2);
				} else {
					result.append(RuntimeMessages.AntProcessBuildLogger__minute_3);
				}
			}
			if (seconds > 0) {
				if (minutes > 0) {
					result.append(' ');
				}
				result.append(seconds);
			
				if (seconds > 1) {
					result.append(RuntimeMessages.AntProcessBuildLogger__seconds_4);
				} else {
					result.append(RuntimeMessages.AntProcessBuildLogger__second_5);
				} 
			}
			if (seconds == 0 && minutes == 0) {
				result.append(milliseconds);
				result.append(RuntimeMessages.AntProcessBuildLogger__milliseconds_6);
			}
			
			result.append(System.getProperty("line.separator")); //$NON-NLS-1$
			return result.toString();
		}
	
	/* (non-Javadoc)
	 * @see org.apache.tools.ant.BuildListener#messageLogged(org.apache.tools.ant.BuildEvent)
	 */
	public void messageLogged(BuildEvent event) {
		if (event.getPriority() > getMessageOutputLevel()) {
			return;
		}
		if (event.getMessage() != null && event.getMessage().length() > 0) {
			logMessage(event.getMessage(), event, -1);
		}
	}

	/* (non-Javadoc)
	 * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent)
	 */
	public void targetStarted(BuildEvent event) {
		if (Project.MSG_INFO > getMessageOutputLevel()) {
			return;
		}
		Target target= event.getTarget();
		StringBuffer msg= new StringBuffer(System.getProperty("line.separator")); //$NON-NLS-1$
		String targetName= target.getName();
		msg.append(targetName);
		msg.append(':');
		String message= msg.toString();
		Location location= AntDebugState.getLocation(target);
		if (location != null && location != Location.UNKNOWN_LOCATION) {
			IRegion region = new Region(0, targetName.length());
			AntProcess antProcess = getAntProcess(fProcessId);
			AntLaunch antLaunch = (AntLaunch)antProcess.getLaunch();
			antLaunch.addLinkDescriptor(message, location.getFileName(), location.getLineNumber(), region.getOffset(), region.getLength());
		}
		logMessage(message, event, Project.MSG_INFO);
	}
	
	private boolean loggingToLogFile() {
		//check if user has designated to log to a log file
		return getErrorPrintStream() != null && getErrorPrintStream() != System.err;
	}
}
