/*******************************************************************************
 * Copyright (c) 2005, 2013 Oracle. All rights reserved.
 * 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/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.core.internal.utility.jdt;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jpt.common.core.utility.jdt.AnnotationEditFormatter;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

/**
 * This implementation will clean up some of the nasty Eclipse annotation
 * formatting (or lack thereof); e.g. arrays of annotations.
 */
public final class DefaultAnnotationEditFormatter
	implements AnnotationEditFormatter
{
	private static final DefaultAnnotationEditFormatter INSTANCE = new DefaultAnnotationEditFormatter();

	/**
	 * Return the singleton.
	 */
	public static DefaultAnnotationEditFormatter instance() {
		return INSTANCE;
	}

	/**
	 * Ensure single instance.
	 */
	private DefaultAnnotationEditFormatter() {
		super();
	}

	/**
	 * TODO
	 */
	public void format(IDocument doc, TextEdit editTree) throws MalformedTreeException, BadLocationException {
		TextEdit[] edits = editTree.getChildren();
		int len = edits.length;
		if (len == 0) {
			return;
		}

		MultiTextEdit extraEdits = new MultiTextEdit();
		for (int i = 0; i < len; i++) {
			TextEdit edit1 = edits[i];
			if ( ! (edit1 instanceof InsertEdit)) {
				continue;  // if the edit is not an insert, skip to the next edit
			}
			InsertEdit insert1 = (InsertEdit) edit1;
			int j = i + 1;
			if (j < len) {
				TextEdit edit2 = edits[j];
				if (edit2 instanceof InsertEdit) {
					InsertEdit insert2 = (InsertEdit) edit2;
					String text1 = insert1.getText();
					String text2 = insert2.getText();
					int offset1 = insert1.getOffset();
					int offset2 = insert2.getOffset();
					if (this.stringIsAnnotation(text1) && text2.equals(" ")) { //$NON-NLS-1$
						// an annotation was inserted before something on the same line;
						// replace the trailing space with a newline and appropriate indent
						extraEdits.addChild(new ReplaceEdit(offset2, 1, this.buildCR(doc, offset2)));
						i++;  // jump the index past 'edit2'
						continue;  // go to the next edit
					}
					int comma1Length = this.commaLength(text1);
					if ((comma1Length != 0) && this.stringIsAnnotation(text2)) {
						// an annotation was inserted in an array initializer on the
						// same line as the previous array element;
						// replace the preceding space with a newline and appropriate indent
						extraEdits.addChild(new ReplaceEdit(offset1 + comma1Length, text1.length() - comma1Length, this.buildCR(doc, offset1)));
						i++;  // jump the index past 'edit2'
						continue;  // go to the next edit
					}
				}
			}
			this.formatArrayInitializer(doc, insert1, extraEdits);
		}
		extraEdits.apply(doc, TextEdit.NONE);
	}

	/**
	 * If the insert edit is inserting an annotation containing an array of annotations as
	 * its value then format them nicely.
	 */
	private void formatArrayInitializer(IDocument doc, InsertEdit insertEdit, MultiTextEdit extraEdits) throws BadLocationException {
		String s = insertEdit.getText();
		if ( ! this.stringIsAnnotation(s)) {
			return;
		}
		int len = s.length();
		int pos = 1;  // skip '@'
		while (pos < len) {
			char c = s.charAt(pos);
			pos++;  // bump to just past first '('
			if (c == '(') {
				break;
			}
		}
		if (pos == len) {
			return;  // reached end of string
		}
		while (pos < len) {
			char c = s.charAt(pos);
			pos++;  // bump to just past first '{'
			if (c == '{') {
				break;
			}
			if (c != ' ') {
				return;
			}
		}
		if (pos == len) {
			return;  // reached end of string
		}
		// now look for '@' not inside parentheses and put in 
		// line delimeter and indent string before each
		int offset = insertEdit.getOffset();
		String indent = null;
		int parenDepth = 0;
		while (pos < len) {
			switch (s.charAt(pos)) {
				case '(' :
					parenDepth++;
					break;
				case ')' :
					parenDepth--;
					break;
				case '@' :
					if (parenDepth == 0) {
						if (indent == null) {
							indent = this.buildCR(doc, offset, "\t");  // TODO use tab preference? //$NON-NLS-1$
						}
						extraEdits.addChild(new InsertEdit(offset + pos, indent));
					}
					break;
				case '}' :
					if (parenDepth == 0) {
						extraEdits.addChild(new InsertEdit(offset + pos, this.buildCR(doc, offset)));
					}
					break;
				default:
					break;
			}
			pos++;
		}
	}

	/**
	 * Build a string containing a line delimeter and indenting characters 
	 * matching the indent level of the line containing the character offset
	 * (i.e. the new line's indent matches the current line).
	 */
	private String buildCR(IDocument doc, int offset) throws BadLocationException {
		return this.buildCR(doc, offset, ""); //$NON-NLS-1$
	}

	private String buildCR(IDocument doc, int offset, String suffix) throws BadLocationException {
		int line = doc.getLineOfOffset(offset);
		StringBuilder sb = new StringBuilder();
		sb.append(doc.getLineDelimiter(line));  // use same CR as current line

		int o = doc.getLineOffset(line);  // match the whitespace of the current line
		char c = doc.getChar(o++);
		while ((c == ' ') || (c == '\t')) {
			sb.append(c);
			c = doc.getChar(o++);
		}
		sb.append(suffix);
		return sb.toString();
	}

	/**
	 * Return whether the specified string is an annotation.
	 */
	private boolean stringIsAnnotation(String string) {
		return (string.length() > 1) && string.charAt(0) == '@';
	}

	/**
	 * If the specified string is a single comma, possibly surrounded by
	 * spaces, return the length of the substring containing the
	 * initial spaces and the comma.
	 */
	private int commaLength(String string) {
		boolean comma = false;
		int len = string.length();
		int result = 0;
		for (int i = 0; i < len; i++) {
			switch (string.charAt(i)) {
				case ' ' :
					if ( ! comma) {
						result++;  // space preceding comma
					}
					break;
				case ',' :
					if (comma) {
						return 0;  // second comma!
					}
					comma = true;
					result++;
					break;
				default:
					return 0;  // non-comma, non-space char
			}
		}
		return result;
	}

}
