/*******************************************************************************
 * Copyright (c) 2004, 2013 John-Mason P. Shackelford 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:
 *     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;
	}
}
