/*******************************************************************************
 * Copyright (c) 2018, 2019 Mateusz Matela 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:
 *     Mateusz Matela <mateusz.matela@gmail.com> - Initial API and implementation
 *     
 *******************************************************************************/
package org.eclipse.jdt.internal.formatter;

import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRBRACE;
import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamewhile;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.ModuleDeclaration;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;

/** Implementation of the "Keep braced code on one line" feature. */
public class OneLineEnforcer extends ASTVisitor {
	private final TokenManager tm;
	private final DefaultCodeFormatterOptions options;

	public OneLineEnforcer(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
		this.tm = tokenManager;
		this.options = options;
	}

	@Override
	public boolean preVisit2(ASTNode node) {
		boolean isMalformed = (node.getFlags() & ASTNode.MALFORMED) != 0;
		return !isMalformed;
	}

	@Override
	public void endVisit(TypeDeclaration node) {
		if (node.getParent().getLength() == 0)
			return; // this is a fake block created by parsing in statements mode
		tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(), this.options.keep_type_declaration_on_one_line);
	}

	@Override
	public void endVisit(EnumDeclaration node) {
		List<ASTNode> items = new ArrayList<>();
		items.addAll(node.bodyDeclarations());
		items.addAll(node.enumConstants());
		tryKeepOnOneLine(node, node.getName(), items, this.options.keep_enum_declaration_on_one_line);
	}

	@Override
	public void endVisit(AnnotationTypeDeclaration node) {
		tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(),
				this.options.keep_annotation_declaration_on_one_line);
	}

	@Override
	public void endVisit(AnonymousClassDeclaration node) {
		if (node.getParent() instanceof EnumConstantDeclaration) {
			tryKeepOnOneLine(node, null, node.bodyDeclarations(),
					this.options.keep_enum_constant_declaration_on_one_line);
		} else {
			tryKeepOnOneLine(node, null, node.bodyDeclarations(),
					this.options.keep_anonymous_type_declaration_on_one_line);
		}
	}

	@Override
	public void endVisit(Block node) {
		ASTNode parent = node.getParent();
		List<Statement> statements = node.statements();
		if (parent.getLength() == 0)
			return; // this is a fake block created by parsing in statements mode
		String oneLineOption;
		if (parent instanceof MethodDeclaration) {
			oneLineOption = this.options.keep_method_body_on_one_line;
			if (this.options.keep_simple_getter_setter_on_one_line) {
				MethodDeclaration method = (MethodDeclaration) parent;
				String name = method.getName().getIdentifier();
				Type returnType = method.getReturnType2();
				boolean returnsVoid = returnType instanceof PrimitiveType
						&& ((PrimitiveType) returnType).getPrimitiveTypeCode() == PrimitiveType.VOID;
				boolean isGetter = name.matches("(is|get)\\p{Lu}.*") //$NON-NLS-1$
						&& !method.isConstructor() && !returnsVoid && method.parameters().isEmpty()
						&& statements.size() == 1 && statements.get(0) instanceof ReturnStatement;
				boolean isSetter = name.matches("set\\p{Lu}.*") //$NON-NLS-1$
						&& !method.isConstructor() && returnsVoid && method.parameters().size() == 1
						&& statements.size() == 1 && statements.get(0) instanceof ExpressionStatement
						&& ((ExpressionStatement) statements.get(0)).getExpression() instanceof Assignment;
				if (isGetter || isSetter)
					oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
			}
		} else if (parent instanceof IfStatement && ((IfStatement) parent).getElseStatement() == null) {
			oneLineOption = this.options.keep_if_then_body_block_on_one_line;
			if (this.options.keep_guardian_clause_on_one_line) {
				boolean isGuardian = statements.size() == 1 && (statements.get(0) instanceof ReturnStatement
						|| statements.get(0) instanceof ThrowStatement);
				// guard clause cannot start with a comment: https://bugs.eclipse.org/58565
				int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
				isGuardian = isGuardian && !this.tm.get(openBraceIndex + 1).isComment();
				if (isGuardian)
					oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
			}
		} else if (parent instanceof LambdaExpression) {
			oneLineOption = this.options.keep_lambda_body_block_on_one_line;
		} else if (parent instanceof ForStatement || parent instanceof EnhancedForStatement
				|| parent instanceof WhileStatement) {
			oneLineOption = this.options.keep_loop_body_block_on_one_line;
		} else if (parent instanceof DoStatement) {
			oneLineOption = this.options.keep_loop_body_block_on_one_line;
			int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
			int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
			Token whileToken = this.tm.firstTokenAfter(node, TokenNamewhile);
			int lastIndex = whileToken.getLineBreaksBefore() == 0 ? this.tm.lastIndexIn(parent, -1) : closeBraceIndex;
			tryKeepOnOneLine(openBraceIndex, closeBraceIndex, lastIndex, statements, oneLineOption);
			return;
		} else {
			oneLineOption = this.options.keep_code_block_on_one_line;
		}
		tryKeepOnOneLine(node, null, statements, oneLineOption);
	}

	@Override
	public void endVisit(ModuleDeclaration node) {
		tryKeepOnOneLine(node, node.getName(), node.moduleStatements(), this.options.keep_type_declaration_on_one_line);
	}

	private void tryKeepOnOneLine(ASTNode node, ASTNode nodeBeforeOpenBrace, List<? extends ASTNode> items,
			String oneLineOption) {
		int openBraceIndex = nodeBeforeOpenBrace == null ? this.tm.firstIndexIn(node, TokenNameLBRACE)
				: this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
		int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
		tryKeepOnOneLine(openBraceIndex, closeBraceIndex, closeBraceIndex, items, oneLineOption);
	}

	private void tryKeepOnOneLine(int openBraceIndex, int closeBraceIndex, int lastIndex, List<? extends ASTNode> items,
			String oneLineOption) {
		if (DefaultCodeFormatterConstants.ONE_LINE_NEVER.equals(oneLineOption))
			return;
		if (DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY.equals(oneLineOption) && !items.isEmpty())
			return;
		if (DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM.equals(oneLineOption) && items.size() > 1)
			return;
		if (DefaultCodeFormatterConstants.ONE_LINE_PRESERVE.equals(oneLineOption)
				&& this.tm.countLineBreaksBetween(this.tm.get(openBraceIndex), this.tm.get(lastIndex)) > 0)
			return;

		Set<Integer> breakIndexes = items.stream().map(n -> this.tm.firstIndexIn(n, -1)).collect(Collectors.toSet());
		breakIndexes.add(openBraceIndex + 1);
		breakIndexes.add(closeBraceIndex);
		Token prev = this.tm.get(openBraceIndex);
		int startPos = this.tm.getPositionInLine(openBraceIndex);
		int pos = startPos + this.tm.getLength(prev, startPos);
		for (int i = openBraceIndex + 1; i <= lastIndex; i++) {
			Token token = this.tm.get(i);
			int preexistingBreaks = this.tm.countLineBreaksBetween(prev, token);
			if (this.options.number_of_empty_lines_to_preserve > 0 && preexistingBreaks > 1)
				return; // blank line will be preserved
			boolean isSpace = prev.isSpaceAfter() || token.isSpaceBefore();
			if (prev.isComment() || token.isComment()) {
				if (preexistingBreaks > 0)
					return; // line break around a comment will be preserved
				char charBefore = this.tm.charAt(token.originalStart - 1);
				isSpace = isSpace || charBefore == ' ' || charBefore == '\t';
			}
			if (prev.getLineBreaksAfter() > 0 || token.getLineBreaksBefore() > 0) {
				if (!breakIndexes.contains(i))
					return; // extra line break within an item, can't remove it
				isSpace = isSpace || !(i == closeBraceIndex && i == openBraceIndex + 1);
			}
			if (isSpace)
				pos++;
			pos += this.tm.getLength(token, pos);
			prev = token;
		}
		if (!items.isEmpty()) {
			if (items.get(0).getParent().getParent() instanceof LambdaExpression)
				pos -= startPos; // lambda body could be put in a wrapped line, so only check its own width
			if (pos > this.options.page_width)
				return; // line width limit exceeded
		}

		for (Integer i : breakIndexes) {
			prev = this.tm.get(i - 1);
			prev.clearLineBreaksAfter();
			Token token = this.tm.get(i);
			token.clearLineBreaksBefore();
			if (!items.isEmpty())
				token.spaceBefore();
		}
	}
}
