/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.ui.editor.text;

import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.AbstractFileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PatternSet;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.launching.debug.model.AntProperty;
import org.eclipse.ant.internal.launching.debug.model.AntStackFrame;
import org.eclipse.ant.internal.launching.debug.model.AntValue;
import org.eclipse.ant.internal.ui.editor.AntEditor;
import org.eclipse.ant.internal.ui.editor.AntEditorSourceViewerConfiguration;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntModel;
import org.eclipse.ant.internal.ui.model.AntPropertyNode;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextHoverExtension;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.EditorsUI;

public class XMLTextHover implements ITextHover, ITextHoverExtension, IInformationProviderExtension2 {

	private AntEditor fEditor;

	public XMLTextHover(AntEditor editor) {
		super();
		fEditor = editor;
	}

	/*
	 * Formats a message as HTML text. Expects the message to already be properly escaped
	 */
	private String formatMessage(String message) {
		StringBuilder buffer = new StringBuilder();
		HTMLPrinter.addPageProlog(buffer);
		HTMLPrinter.addParagraph(buffer, message);
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}

	/*
	 * Formats a message as HTML text.
	 */
	private String formatPathMessage(String[] list) {
		StringBuilder buffer = new StringBuilder();
		HTMLPrinter.addPageProlog(buffer);
		HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_4);
		HTMLPrinter.startBulletList(buffer);
		for (String element : list) {
			HTMLPrinter.addBullet(buffer, element);
		}
		HTMLPrinter.endBulletList(buffer);
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}

	@Override
	public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {

		if (!(textViewer instanceof ISourceViewer)) {
			return null;
		}

		ISourceViewer sourceViewer = (ISourceViewer) textViewer;
		IAnnotationModel model = sourceViewer.getAnnotationModel();

		if (model != null) {
			String message = getAnnotationModelHoverMessage(model, hoverRegion);
			if (message != null) {
				return message;
			}
		}

		AntModel antModel = fEditor.getAntModel();
		if (antModel == null) { // the ant model has not been created yet
			return null;
		}

		return getAntModelHoverMessage(antModel, hoverRegion, textViewer);

	}

	private String getAntModelHoverMessage(AntModel antModel, IRegion hoverRegion, ITextViewer textViewer) {
		try {
			IDocument document = textViewer.getDocument();
			int offset = hoverRegion.getOffset();
			int length = hoverRegion.getLength();
			String text = document.get(offset, length);
			String value;
			AntElementNode node = antModel.getNode(offset, false);
			if (document.get(offset - 2, 2).equals("${") || node instanceof AntPropertyNode) { //$NON-NLS-1$
				AntStackFrame frame = getFrame();
				if (frame != null) {// active Ant debug session
					AntProperty property = frame.findProperty(text);
					if (property != null) {
						return ((AntValue) property.getValue()).getValueString();
					}
				}
				value = antModel.getPropertyValue(text);
				if (value != null) {
					return formatMessage(HTMLPrinter.convertToHTMLContent(value));
				}
			}
			value = antModel.getTargetDescription(text);
			if (value != null) {
				return formatMessage(HTMLPrinter.convertToHTMLContent(value));
			}
			Object referencedObject = antModel.getReferenceObject(text);
			if (referencedObject != null) {
				if (referencedObject instanceof Path) {
					return formatPathMessage(((Path) referencedObject).list());
				} else if (referencedObject instanceof PatternSet) {
					return formatPatternSetMessage((PatternSet) referencedObject);
				} else if (referencedObject instanceof AbstractFileSet) {
					return formatFileSetMessage((AbstractFileSet) referencedObject);
				}
			}
		}
		catch (BadLocationException e) {
			// do nothing
		}
		catch (BuildException be) {
			return be.getMessage();
		}

		return null;
	}

	private String getAnnotationModelHoverMessage(IAnnotationModel model, IRegion hoverRegion) {
		Iterator<Annotation> e = model.getAnnotationIterator();
		while (e.hasNext()) {
			Annotation a = e.next();
			if (a instanceof XMLProblemAnnotation) {
				Position p = model.getPosition(a);
				if (p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
					String msg = a.getText();
					if (msg != null && msg.trim().length() > 0) {
						return formatMessage(msg);
					}
				}
			}
		}
		return null;
	}

	private String formatFileSetMessage(AbstractFileSet set) {
		FileScanner fileScanner = new FileScanner();
		IAntModel antModel = fEditor.getAntModel();
		Project project = antModel.getProjectNode().getProject();
		set.setupDirectoryScanner(fileScanner, project);
		String[] excludedPatterns = fileScanner.getExcludesPatterns();
		String[] includesPatterns = fileScanner.getIncludePatterns();
		return formatSetMessage(includesPatterns, excludedPatterns);
	}

	private String formatPatternSetMessage(PatternSet set) {
		IAntModel antModel = fEditor.getAntModel();
		Project project = antModel.getProjectNode().getProject();
		String[] includes = set.getIncludePatterns(project);
		String[] excludes = set.getExcludePatterns(project);
		return formatSetMessage(includes, excludes);
	}

	private String formatSetMessage(String[] includes, String[] excludes) {
		StringBuilder buffer = new StringBuilder();
		HTMLPrinter.addPageProlog(buffer);
		if (includes != null && includes.length > 0) {
			HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_5);
			for (String include : includes) {
				HTMLPrinter.addBullet(buffer, include);
			}
		}
		HTMLPrinter.addParagraph(buffer, IAntCoreConstants.EMPTY_STRING);
		HTMLPrinter.addParagraph(buffer, IAntCoreConstants.EMPTY_STRING);
		if (excludes != null && excludes.length > 0) {
			HTMLPrinter.addSmallHeader(buffer, AntEditorTextMessages.XMLTextHover_6);
			for (String exclude : excludes) {
				HTMLPrinter.addBullet(buffer, exclude);
			}
		}
		HTMLPrinter.addPageEpilog(buffer);
		return buffer.toString();
	}

	@Override
	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
		if (textViewer != null) {
			return getRegion(textViewer, offset);
		}
		return null;
	}

	public static IRegion getRegion(ITextViewer textViewer, int offset) {
		IDocument document = textViewer.getDocument();

		int start = -1;
		int end = -1;
		IRegion region = null;
		try {
			int pos = offset;
			char c;

			if (document.getChar(pos) == '"') {
				pos--;
			}
			while (pos >= 0) {
				c = document.getChar(pos);
				if (c != '.' && c != '-' && c != '/' && c != '\\' && c != ' ' && c != ')' && c != '(' && c != ':'
						&& !Character.isJavaIdentifierPart(c) && pos != offset)
					break;
				--pos;
			}

			start = pos;

			pos = offset;
			int length = document.getLength();

			while (pos < length) {
				c = document.getChar(pos);
				if (c != '.' && c != '-' && c != '/' && c != '\\' && c != ' ' && c != ')' && c != '(' && c != ':'
						&& !Character.isJavaIdentifierPart(c))
					break;
				if (c == '/' && (document.getLength() - 1) > (pos + 1) && document.getChar(pos + 1) == '>') {
					// e.g. <name/>
					break;
				}
				++pos;
			}

			end = pos;

		}
		catch (BadLocationException x) {
			// do nothing
		}

		if (start > -1 && end > -1) {
			if (start == offset && end == offset) {
				return new Region(offset, 0);
			} else if (start == offset) {
				return new Region(start, end - start);
			} else {
				try { // correct for spaces at beginning or end
					while (document.getChar(start + 1) == ' ') {
						start++;
					}
					while (document.getChar(end - 1) == ' ') {
						end--;
					}
				}
				catch (BadLocationException e) {
					// do nothing
				}
				region = new Region(start + 1, end - start - 1);
			}
		}

		if (region != null) {
			try {
				char c = document.getChar(region.getOffset() - 1);
				if (c == '"') {
					if (document.get(offset, region.getLength()).indexOf(',') != -1) {
						region = cleanRegionForNonProperty(offset, document, region);
					}
				} else if (c != '{') {
					region = cleanRegionForNonProperty(offset, document, region);
				}
			}
			catch (BadLocationException e) {
				// do nothing
			}
		}

		return region;
	}

	private static IRegion cleanRegionForNonProperty(int offset, IDocument document, IRegion region) throws BadLocationException {
		// do not allow spaces in region that is not a property
		IRegion r = region;
		String text = document.get(r.getOffset(), r.getLength());
		if (text.startsWith("/")) { //$NON-NLS-1$
			text = text.substring(1);
			r = new Region(r.getOffset() + 1, r.getLength() - 1);
		}
		StringTokenizer tokenizer = new StringTokenizer(text, " "); //$NON-NLS-1$
		if (tokenizer.countTokens() != 1) {
			while (tokenizer.hasMoreTokens()) {
				String token = tokenizer.nextToken();
				int index = text.indexOf(token);
				if (r.getOffset() + index <= offset && r.getOffset() + index + token.length() >= offset) {
					r = new Region(r.getOffset() + index, token.length());
					break;
				}
			}
		}

		return r;
	}

	@Override
	public IInformationControlCreator getHoverControlCreator() {
		return new IInformationControlCreator() {
			@Override
			public IInformationControl createInformationControl(Shell parent) {
				return new DefaultInformationControl(parent, EditorsUI.getTooltipAffordanceString());
			}
		};
	}

	/**
	 * Returns the stack frame in which to search for properties, or <code>null</code> if none.
	 * 
	 * @return the stack frame in which to search for properties, or <code>null</code> if none
	 */
	private AntStackFrame getFrame() {
		IAdaptable adaptable = DebugUITools.getDebugContext();
		if (adaptable != null) {
			return adaptable.getAdapter(AntStackFrame.class);
		}
		return null;
	}

	/**
	 * @since 3.3
	 */
	@Override
	public IInformationControlCreator getInformationPresenterControlCreator() {
		return AntEditorSourceViewerConfiguration.getInformationPresenterControlCreator();
	}
}