/*******************************************************************************
 * Copyright (c) 2000, 2004 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.jdt.internal.formatter.comment;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ILineTracker;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextUtilities;

import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;


/**
 * Javadoc region in a source code document.
 * 
 * @since 3.0
 */
public class JavaDocRegion extends MultiCommentRegion implements IJavaDocTagConstants {

	/** The positions of code ranges */
	private final ArrayList fCodePositions= new ArrayList();
	 
	/** Should HTML tags be formatted? */
	private final boolean fFormatHtml;

	/** Should source code regions be formatted? */
	private final boolean fFormatSource;
	
 	/**
	 * Creates a new Javadoc region.
	 * 
	 * @param document the document which contains the comment region
	 * @param position the position of this comment region in the document
	 * @param formatter the given formatter
	 */	
	public JavaDocRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
		super(document, position, formatter);

		fFormatSource= this.preferences.comment_format_source;
		fFormatHtml= this.preferences.comment_format_html;
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canFormat(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
	 */
	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
		
		if (previous != null) {
			
			final boolean isCurrentCode= next.hasAttribute(COMMENT_CODE);
			final boolean isLastCode= previous.hasAttribute(COMMENT_CODE);
			
			final int base= getOffset();
			
			if (!isLastCode && isCurrentCode)
				fCodePositions.add(new Position(base + previous.getOffset()));
			else if (isLastCode && !isCurrentCode)
				fCodePositions.add(new Position(base + next.getOffset() + next.getLength()));
			
			if (previous.hasAttribute(COMMENT_IMMUTABLE) && next.hasAttribute(COMMENT_IMMUTABLE))
				return false;
			
			return true;
		}
		return false;
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#formatRegion(java.lang.String, int)
	 */
	protected final void formatRegion(final String indentation, final int width) {
	
		super.formatRegion(indentation, width);
		
		if (fFormatSource) {
			
			try {
				
				if (fCodePositions.size() > 0) {
					
					int begin= 0;
					int end= 0;
					
					Position position= null;
					
					final IDocument document= getDocument();
					
					for (int index= fCodePositions.size() - 1; index >= 0;) {
						
						position= (Position)fCodePositions.get(index--);
						begin= position.getOffset();
						
						if (index >= 0) {
							position= (Position)fCodePositions.get(index--);
							end= position.getOffset();
						} else {
							/* 
							 * Handle missing closing tag
							 * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=57011
							 */
							position= null;
							end= getOffset() + getLength() - MultiCommentLine.MULTI_COMMENT_END_PREFIX.trim().length();
							while (end > begin && Character.isWhitespace(document.getChar(end - 1)))
								end--;
						}
						
						String snippet= document.get(begin, end - begin);
						snippet= preprocessCodeSnippet(snippet);
						snippet= formatCodeSnippet(snippet);
						snippet= postprocessCodeSnippet(snippet, indentation);
						
						logEdit(snippet, begin - getOffset(), end - begin);
					}
				}
			} catch (BadLocationException e) {
				// Can not happen
				CommentFormatterUtil.log(e);
			}
		}
	}

	/**
	 * Preprocess a given code snippet.
	 * 
	 * @param snippet the code snippet
	 * @return the preprocessed code snippet
	 */
	private String preprocessCodeSnippet(String snippet) {
		// strip content prefix
		StringBuffer buffer= new StringBuffer();
		ILineTracker tracker= new DefaultLineTracker();
		String contentPrefix= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX.trim();
		
		buffer.setLength(0);
		buffer.append(snippet);
		tracker.set(snippet);
		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--) {
			int lineOffset;
			try {
				lineOffset= tracker.getLineOffset(line);
			} catch (BadLocationException e) {
				// Can not happen
				CommentFormatterUtil.log(e);
				return snippet;
			}
			int prefixOffset= buffer.indexOf(contentPrefix, lineOffset);
			if (prefixOffset >= 0 && buffer.substring(lineOffset, prefixOffset).trim().length() == 0)
				buffer.delete(lineOffset, prefixOffset + contentPrefix.length());
		}
		
		return convertHtml2Java(buffer.toString());
	}

	/**
	 * Format the given code snippet
	 * 
	 * @param snippet the code snippet
	 * @return the formatted code snippet
	 */
	private String formatCodeSnippet(String snippet) {
		String lineDelimiter= TextUtilities.getDefaultLineDelimiter(getDocument());
		TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN, snippet, 0, lineDelimiter, this.preferences.getMap());
		if (edit != null)
			snippet= CommentFormatterUtil.evaluateFormatterEdit(snippet, edit, null);
		return snippet;
	}

	/**
	 * Postprocesses the given code snippet with the given indentation.
	 * 
	 * @param snippet the code snippet
	 * @param indentation the indentation
	 * @return the postprocessed code snippet
	 */
	private String postprocessCodeSnippet(String snippet, String indentation) {
		// patch content prefix
		StringBuffer buffer= new StringBuffer();
		ILineTracker tracker= new DefaultLineTracker();
		String patch= indentation + MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;

		buffer.setLength(0);
		buffer.append(getDelimiter());
		buffer.append(convertJava2Html(snippet));
		buffer.append(getDelimiter());
		tracker.set(buffer.toString());
		
		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--)
			try {
				buffer.insert(tracker.getLineOffset(line), patch);
			} catch (BadLocationException e) {
				// Can not happen
				CommentFormatterUtil.log(e);
				return snippet;
			}
		
		return buffer.toString();
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlRanges()
	 */
	protected final void markHtmlRanges() {

		markTagRanges(JAVADOC_IMMUTABLE_TAGS, COMMENT_IMMUTABLE, true);

		if (fFormatSource)
			markTagRanges(JAVADOC_CODE_TAGS, COMMENT_CODE, false);
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
	 */
	protected final void markHtmlTag(final CommentRange range, final String token) {

		if (range.hasAttribute(COMMENT_HTML)) {

			range.markHtmlTag(JAVADOC_IMMUTABLE_TAGS, token, COMMENT_IMMUTABLE, true, true);
			if (fFormatHtml) {

				range.markHtmlTag(JAVADOC_SEPARATOR_TAGS, token, COMMENT_SEPARATOR, true, true);
				range.markHtmlTag(JAVADOC_BREAK_TAGS, token, COMMENT_BREAK, false, true);
				range.markHtmlTag(JAVADOC_SINGLE_BREAK_TAG, token, COMMENT_BREAK, true, false);
				range.markHtmlTag(JAVADOC_NEWLINE_TAGS, token, COMMENT_NEWLINE, true, false);

			} else
				range.markHtmlTag(JAVADOC_CODE_TAGS, token, COMMENT_SEPARATOR, true, true);
		}
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markJavadocTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
	 */
	protected final void markJavadocTag(final CommentRange range, final String token) {

		range.markPrefixTag(JAVADOC_PARAM_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_PARAMETER);

		if (token.charAt(0) == JAVADOC_TAG_PREFIX && !range.hasAttribute(COMMENT_PARAMETER))
			range.setAttribute(COMMENT_ROOT);
	}

	/**
	 * Marks the comment region with the HTML range tag.
	 * 
	 * @param tags the HTML tag which confines the HTML range
	 * @param attribute the attribute to set if the comment range is in the
	 *                HTML range
	 * @param html <code>true</code> iff the HTML tags in this HTML range
	 *                should be marked too, <code>false</code> otherwise
	 */
	protected final void markTagRanges(final String[] tags, final int attribute, final boolean html) {
		
		int level= 0;
		int count= 0;
		String token= null;
		CommentRange current= null;
		
		for (int index= 0; index < tags.length; index++) {
			
			level= 0;
			for (final Iterator iterator= getRanges().iterator(); iterator.hasNext();) {
				
				current= (CommentRange)iterator.next();
				count= current.getLength();
				
				if (count > 0 || level > 0) { // PR44035: when inside a tag, mark blank lines as well to get proper snippet formatting
					
					token= getText(current.getOffset(), current.getLength());
					level= current.markTagRange(token, tags[index], level, attribute, html);
				}
			}
		}
	}

	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
	 */
	protected boolean canAppend(CommentLine line, CommentRange previous, CommentRange next, int index, int count) {
		// don't append code sections
		if (next.hasAttribute(COMMENT_CODE | COMMENT_FIRST_TOKEN) && line.getSize() != 0)
			return false;
		return super.canAppend(line, previous, next, index, count);
	}

	/**
	 * Converts <code>formatted</code> into valid html code suitable to be
	 * put inside &lt;pre&gt;&lt;/pre&gt; tags by replacing any html symbols
	 * by the relevant entities.
	 * 
	 * @param formatted the formatted java code
	 * @return html version of the formatted code
	 */
	private String convertJava2Html(String formatted) {
		Java2HTMLEntityReader reader= new Java2HTMLEntityReader(new StringReader(formatted));
		char[] buf= new char[256];
		StringBuffer buffer= new StringBuffer();
		int l;
		try {
			do {
				l= reader.read(buf);
				if (l != -1)
					buffer.append(buf, 0, l);
			} while (l > 0);
			return buffer.toString();
		} catch (IOException e) {
			return formatted;
		}
	}

	/**
	 * Converts <code>html</code> into java code suitable for formatting
	 * by replacing any html entities by their plain text representation.
	 * 
	 * @param html html code, may contain html entities
	 * @return plain textified version of <code>html</code>
	 */
	private String convertHtml2Java(String html) {
		HTMLEntity2JavaReader reader= new HTMLEntity2JavaReader(new StringReader(html));
		char[] buf= new char[html.length()]; // html2text never gets longer, only shorter!
		
		try {
			int read= reader.read(buf);
			return new String(buf, 0, read);
		} catch (IOException e) {
			return html;
		}
	}
	
	/*
	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
	 * @since 3.1
	 */
	protected CommentLine createLine() {
		return new JavaDocLine(this);
	}
}
