/*******************************************************************************
 * Copyright (c) 2004, 2013 John-Mason P. Shackelford 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:
 *     John-Mason P. Shackelford - initial API and implementation
 *     IBM Corporation - bug fixes
 *******************************************************************************/
package org.eclipse.ant.internal.ui.editor.formatter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.editor.templates.AntContext;
import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant;
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.IAntModel;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultPositionUpdater;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateVariable;

/**
 * Utility class for using the ant code formatter in contexts where an IDocument containing the text to format is not readily available.
 */
public class XmlFormatter {

	private static final String POS_CATEGORY = "tempAntFormatterCategory"; //$NON-NLS-1$

	/**
	 * Format the text using the ant code formatter.
	 * 
	 * @param text
	 *            The text to format. Must be a non-null value.
	 * @param prefs
	 *            Preferences to use for this format operation. If null, the preferences currently set in the plug-in's preferences store are used.
	 * @return The formatted text.
	 */
	public static String format(String text, FormattingPreferences prefs) {

		return format(text, prefs, -1);
	}

	private static String format(String text, FormattingPreferences prefs, int indent) {
		Assert.isNotNull(text);

		FormattingPreferences applyPrefs;
		if (prefs == null) {
			applyPrefs = new FormattingPreferences();
		} else {
			applyPrefs = prefs;
		}

		IDocument doc = new Document();
		doc.set(text);
		new AntDocumentSetupParticipant().setup(doc);

		format(applyPrefs, doc, indent);

		return doc.get();
	}

	private static void format(FormattingPreferences prefs, IDocument doc, int indent) {
		MultiPassContentFormatter formatter = new MultiPassContentFormatter(AntDocumentSetupParticipant.ANT_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);

		formatter.setMasterStrategy(new XmlDocumentFormattingStrategy(prefs, indent));
		formatter.setSlaveStrategy(new XmlElementFormattingStrategy(prefs), AntEditorPartitionScanner.XML_TAG);
		formatter.format(doc, new Region(0, doc.getLength()));
	}

	/**
	 * Format the text using the ant code formatter using the preferences settings in the plug-in preference store.
	 * 
	 * @param text
	 *            The text to format. Must be a non-null value.
	 * @return The formatted text.
	 */
	public static String format(String text) {
		return format(text, null);
	}

	public static void format(TemplateBuffer templateBuffer, AntContext antContext, FormattingPreferences prefs) {
		String templateString = templateBuffer.getString();
		IDocument fullDocument = new Document(antContext.getDocument().get());

		int completionOffset = antContext.getCompletionOffset();
		try {
			// trim any starting whitespace
			IRegion lineRegion = fullDocument.getLineInformationOfOffset(completionOffset);
			String lineString = fullDocument.get(lineRegion.getOffset(), lineRegion.getLength());
			lineString = trimBegin(lineString);
			fullDocument.replace(lineRegion.getOffset(), lineRegion.getLength(), lineString);
		}
		catch (BadLocationException e1) {
			return;
		}
		TemplateVariable[] variables = templateBuffer.getVariables();
		int[] offsets = variablesToOffsets(variables, completionOffset);

		IDocument origTemplateDoc = new Document(fullDocument.get());
		try {
			origTemplateDoc.replace(completionOffset, antContext.getCompletionLength(), templateString);
		}
		catch (BadLocationException e) {
			return; // don't format if the document has changed
		}

		IDocument templateDocument = createDocument(origTemplateDoc.get(), createPositions(offsets));

		String leadingText = getLeadingText(fullDocument, antContext.getAntModel(), completionOffset);
		String newTemplateString = leadingText + templateString;
		int indent = XmlDocumentFormatter.computeIndent(leadingText, prefs.getTabWidth());

		newTemplateString = format(newTemplateString, prefs, indent);

		try {
			templateDocument.replace(completionOffset, templateString.length(), newTemplateString);
		}
		catch (BadLocationException e) {
			return;
		}
		Position[] positions = null;
		try {
			positions = templateDocument.getPositions(POS_CATEGORY);
		}
		catch (BadPositionCategoryException e2) {
			// do nothing
		}
		// offsetsToVariables(offsets, variables, completionOffset);
		positionsToVariables(positions, variables, completionOffset);
		templateBuffer.setContent(newTemplateString, variables);
	}

	private static void positionsToVariables(Position[] positions, TemplateVariable[] variables, int start) {
		for (int i = 0; i != variables.length; i++) {
			TemplateVariable variable = variables[i];

			int[] offsets = new int[variable.getOffsets().length];
			for (int j = 0; j != offsets.length; j++) {
				offsets[j] = positions[j].getOffset() - start;
			}

			variable.setOffsets(offsets);
		}
	}

	private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException {
		Document doc = new Document(string);
		try {
			if (positions != null) {

				doc.addPositionCategory(POS_CATEGORY);
				doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
					@Override
					protected boolean notDeleted() {
						if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
							fPosition.offset = fOffset + fLength; // deleted positions: set to end of remove
							return false;
						}
						return true;
					}
				});
				for (int i = 0; i < positions.length; i++) {
					try {
						doc.addPosition(POS_CATEGORY, positions[i]);
					}
					catch (BadLocationException e) {
						throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " //$NON-NLS-1$//$NON-NLS-2$
								+ positions[i].length + ", string size: " + string.length(), e); //$NON-NLS-1$
					}
				}
			}
		}
		catch (BadPositionCategoryException cannotHappen) {
			// can not happen: category is correctly set up
		}
		return doc;
	}

	public static String trimBegin(String toBeTrimmed) {

		int i = 0;
		while ((i != toBeTrimmed.length()) && Character.isWhitespace(toBeTrimmed.charAt(i))) {
			i++;
		}

		return toBeTrimmed.substring(i);
	}

	private static int[] variablesToOffsets(TemplateVariable[] variables, int start) {
		List<Integer> list = new ArrayList<>();
		for (int i = 0; i != variables.length; i++) {
			int[] offsets = variables[i].getOffsets();
			for (int j = 0; j != offsets.length; j++) {
				list.add(Integer.valueOf(offsets[j]));
			}
		}

		int[] offsets = new int[list.size()];
		for (int i = 0; i != offsets.length; i++) {
			offsets[i] = list.get(i).intValue() + start;
		}

		Arrays.sort(offsets);

		return offsets;
	}

	/**
	 * Returns the indentation level at the position of code completion.
	 */
	private static String getLeadingText(IDocument document, IAntModel model, int completionOffset) {
		AntProjectNode project = model.getProjectNode(false);
		if (project == null) {
			return IAntCoreConstants.EMPTY_STRING;
		}
		AntElementNode node = project.getNode(completionOffset);// - fAccumulatedChange);
		if (node == null) {
			return IAntCoreConstants.EMPTY_STRING;
		}

		StringBuffer buf = new StringBuffer();
		buf.append(XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), document));
		buf.append(XmlDocumentFormatter.createIndent());
		return buf.toString();
	}

	private static Position[] createPositions(int[] positions) {
		Position[] p = null;

		if (positions != null) {
			p = new Position[positions.length];
			for (int i = 0; i < positions.length; i++) {
				p[i] = new Position(positions[i], 0);
			}
		}
		return p;
	}
}
