/*******************************************************************************
 * Copyright (c) 2000, 2005 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.ant.internal.ui.launchConfigurations;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.console.FileLink;
import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.console.IHyperlink;

/**
 * Manages task links per process. As messages are logged to the console from
 * build events, hyperlinks are created to link task names to the associated ant
 * buildfile. The build logger registers a task hyperlink with this manager for
 * each build event associated with a task. When the associated line is later
 * appended to the console, the corresponding text region in the console
 * document is determined (as the length of a console document can not be
 * determined beforehand), and the hyperlink is added to the document.
 * The new line is added to the console, information from that line 
 * may be stored to process future incoming tasks hyperlinks.
 */
public class TaskLinkManager {
	
	/**
	 * A map of processes to lists of queued task hyperlink entries
	 */
	private static Map fgProcessToLinks;
	
	/**
	 * A map of processes to lists of queued new line regions
	 */
	private static Map fgProcessToNewLines;
	
	private static List fgAntBuilds;
	
	private static class HyperlinkEntry {
		private IHyperlink fLink;
		private IRegion fRegion;
		private String fMessage;
		
		public HyperlinkEntry(IHyperlink link, IRegion region, String message) {
			fLink = link;
			fRegion = region;	
			fMessage = message;
		}
		
		public IRegion getRegion() {
			return fRegion;
		}
		
		public IHyperlink getLink() {
			return fLink;
		}
		
		public String getMessage() {
			return fMessage;
		}
	}
	
	private static class LineEntry {
		private IConsole fConsole;
		private IRegion fRegion;
	
		public LineEntry(IConsole console, IRegion region) {
			fConsole = console;
			fRegion = region;	
		}
	
		public IRegion getRegion() {
			return fRegion;
		}
	
		public IConsole getConsole() {
			return fConsole;
		}
	}

	/**
	 * Not to be called.
	 */
	private TaskLinkManager() {
		super();
	}
	
	/**
	 * Registers a hyperlink for the given process and task name. The given
	 * region is relative to the beginning of the line (not the document).
	 * 
	 * @param process the process associated with the link
	 * @param link the link for the process
	 * @param region The region within the line
	 * @param message The message related to the link
	 */
	public static synchronized void addTaskHyperlink(IProcess process, IHyperlink link, IRegion region, String message) {
		if (fgProcessToNewLines != null) {
			List newLines = (List)fgProcessToNewLines.get(process);
			if (newLines != null) {
				for (int index= 0; index < newLines.size(); index++) {
					LineEntry newLine = (LineEntry) newLines.get(index);
					if (addLink(newLine.getConsole(), link, newLine.getRegion(), region, message)) {
						newLines.subList(0, index + 1).clear();
						return;
					}
				}
			}
		}
				
		if (fgProcessToLinks == null) {
			fgProcessToLinks = new HashMap();
			
		}
		List links = (List)fgProcessToLinks.get(process);
		if (links == null) {
			links = new ArrayList(10);
			fgProcessToLinks.put(process, links);
		}
		
		links.add(new HyperlinkEntry(link, region, message));
	}
	
	private static boolean addLink(IConsole console, IHyperlink link, IRegion lineRegion, IRegion region, String message) {
		
		int length = region.getLength();
		
		String text;
		try {
			text = console.getDocument().get(lineRegion.getOffset(), lineRegion.getLength());
		} catch (BadLocationException e) {
			return false;
		}
		if (text.trim().equals(message)) {
			int offset = lineRegion.getOffset() + region.getOffset();
			console.addLink(link, offset, length);
			return true;
		}
		return false;
	}

	/**
	 * A new line has been added to the given console. Adds any task hyperlink
	 * associated with the line, to the console.
	 * The new line may be stored to process future incoming tasks hyperlinks.
	 * 
	 * @param console
	 * @param newLine
	 */
	public static synchronized void processNewLine(IConsole console, IRegion newLine) {
		IProcess process = console.getProcess();
		if (fgAntBuilds != null && fgAntBuilds.contains(process)) {
			if (linkBuildFileMessage(console, newLine)) {
				fgAntBuilds.remove(process);
				return;
			}
		}
		if (fgProcessToLinks == null) {
			addNewLine(console, newLine, process);
			return;
		}
		
		List links = (List)fgProcessToLinks.get(process);
		if (links == null) {
			addNewLine(console, newLine, process);
			return;
		}
		
		for (int index= 0; index < links.size(); index++) {
			HyperlinkEntry link = (HyperlinkEntry) links.get(index);
			if (addLink(console, link.getLink(), newLine, link.getRegion(), link.getMessage())) {
				links.subList(0, index + 1).clear();
				return;
			}
		}
	}
	
	private static void addNewLine(IConsole console, IRegion newLine, IProcess process) {
		if (fgProcessToNewLines == null) {
			fgProcessToNewLines = new HashMap();
		}
		List newLines = (List)fgProcessToNewLines.get(process);
		if (newLines == null) {
			newLines= new ArrayList();
		}
	
		newLines.add(new LineEntry(console, newLine));
		fgProcessToNewLines.put(process, newLines);
	}

	/**
	 * Disposes any information stored for the given process.
	 * 
	 * @param process
	 */
	public static void dispose(IProcess process) {
		if (fgProcessToLinks != null) {
			fgProcessToLinks.remove(process);
		}
		if (fgProcessToNewLines != null) {
			fgProcessToNewLines.remove(process);
		}
		if (fgAntBuilds != null) {
			fgAntBuilds.remove(process);
		}
	}
	
	/**
	 * Registers the specified process as an Ant build process.
	 * Allows for the generation of the "Buildfile: somefile" link in the 
	 * Ant output.
	 * 
	 * @param process
	 */
	public static synchronized void registerAntBuild(IProcess process) {
		if (fgProcessToNewLines != null) {
			List newLines = (List)fgProcessToNewLines.get(process);
			if (newLines != null) {
				for (Iterator iter = newLines.iterator(); iter.hasNext();) {
					LineEntry newLine = (LineEntry) iter.next();
					if (linkBuildFileMessage(newLine.getConsole(), newLine.getRegion())){
						iter.remove();
						return;
					}
				}
			}
		}
		if (fgAntBuilds == null) {
			fgAntBuilds= new ArrayList();
		}
		fgAntBuilds.add(process);
	}
	
	private static boolean linkBuildFileMessage(IConsole console, IRegion region) {
		
		String message= ""; //$NON-NLS-1$
		int offset= region.getOffset();
		try {
			message = console.getDocument().get(offset, region.getLength());
		} catch (BadLocationException e) {
		}
		if (message.startsWith("Buildfile:")) { //$NON-NLS-1$
			String fileName = message.substring(10).trim();
			IFile file = AntUtil.getFileForLocation(fileName, null);
			if (file != null) {
				FileLink link = new FileLink(file, null,  -1, -1, -1);
				console.addLink(link, offset + 11, fileName.length());
				return true;
			}
		}
		return false;
	}
}
