/*******************************************************************************
 * Copyright (c) 2012, 2018 GK Software AG 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:
 *     Stephan Herrmann - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction.proposals;

import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EmptyStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;

import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.fix.FixMessages;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalPositionGroup;

import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.preferences.formatter.FormatterProfileManager;


/**
 * Fix for field related null-issues:
 * <ol>
 * <li>{@link IProblem#NullableFieldReference}</li>
 * <li>{@link IProblem#RequiredNonNullButProvidedSpecdNullable} <em>if relating to a field</em></li>
 * <li>{@link IProblem#RequiredNonNullButProvidedUnknown} <em>if relating to a field</em></li>
 * </ol>
 * Extract the field reference to a fresh local variable.
 * Add a null check for that local variable and move
 * the dereference into the then-block of this null-check:
 * <pre>
 * {@code @Nullable Exception e;}
 * void test() {
 *     e.printStackTrace();
 * }</pre>
 * will be converted to:
 * <pre>
 * {@code @Nullable Exception e;}
 * void test() {
 *     final Exception e2 = e;
 *     if (e2 != null) {
 *         e2.printStackTrace();
 *     } else {
 *         // TODO handle null value
 *     }
 * }</pre>
 * <p>
 * The <code>final</code> keyword is added to remind the user that writing
 * to the local variable has no effect on the original field.</p>
 * <p>Rrespects scoping if the problem occurs inside the initialization
 * of a local variable (by moving statements into the new then block).</p>
 *
 * @since 3.9
 */
public class ExtractToNullCheckedLocalProposal extends LinkedCorrectionProposal {

	private static final String LOCAL_NAME_POSITION_GROUP = "localName"; //$NON-NLS-1$

	/** Protocol for rearranging the bits and pieces into a new code structure. */
	private static abstract class RearrangeStrategy {

		final Statement origStmt;
		final Block block;
		final TextEditGroup group;

		RearrangeStrategy(Statement origStmt, Block block, TextEditGroup group) {
			this.origStmt= origStmt;
			this.block= block;
			this.group= group;
		}
		/** Step 1 of the protocol: insert the new local variable.
		 * @param localDecl new local variable initialized with the original expression */
		public abstract void insertLocalDecl(VariableDeclarationStatement localDecl);
		/** Step 2 of the protocol: create a move target for repositioning the original enclosing statement.
		 * @return a move target representing the original statement */
		public abstract Statement createMoveTargetForOrigStmt();
		/** Step 3 of the protocol: integrate the new if statement into the existing structure.
		 * @param ifStmt the new if statement, fully created
		 * @param thenBlock the then statement of the given if statement (is a block by construction) */
		public abstract void insertIfStatement(IfStatement ifStmt, Block thenBlock);

		public static RearrangeStrategy create(Statement origStmt, ASTRewrite rewrite, TextEditGroup group) {
			ASTNode parent = origStmt.getParent();
			if (parent instanceof Block) {
				Block block= (Block)parent;
				if (origStmt instanceof VariableDeclarationStatement)
					return new ModifyBlockWithLocalDecl(origStmt, block, rewrite, group);
				else
					return new ModifyBlock(origStmt, block, rewrite, group);
			} else {
				return new ReplaceStatement(origStmt, rewrite, group);
			}
		}

		/** Strategy implementation for modifying statement list of the parent block. */
		private static class ModifyBlock extends RearrangeStrategy {

			final ListRewrite blockRewrite;

			ModifyBlock(Statement origStmt, Block enclosingBlock, ASTRewrite rewrite, TextEditGroup group) {
				super(origStmt, enclosingBlock, group);
				// we're going to modify this block, create the rewrite for this task:
				this.blockRewrite= rewrite.getListRewrite(enclosingBlock, Block.STATEMENTS_PROPERTY);
			}
			@Override
			public void insertLocalDecl(VariableDeclarationStatement localDecl) {
				this.blockRewrite.insertBefore(localDecl, this.origStmt, this.group);
			}
			@Override
			public Statement createMoveTargetForOrigStmt() {
				return (Statement) this.blockRewrite.createMoveTarget(this.origStmt, this.origStmt, null, this.group);
			}
			@Override
			public void insertIfStatement(IfStatement ifStmt, Block thenBlock) {
				// inside a block replace old statement with wrapping if-statement
				this.blockRewrite.replace(this.origStmt, ifStmt, this.group);
			}
		}

		/** Variant that also respects scoping of an existing local variable declaration. */
		private static class ModifyBlockWithLocalDecl extends ModifyBlock {
			ModifyBlockWithLocalDecl(Statement origStmt, Block enclosingBlock, ASTRewrite rewrite, TextEditGroup group) {
				super(origStmt, enclosingBlock, rewrite, group);
			}
			@Override
			public void insertIfStatement(IfStatement ifStmt, Block thenBlock) {
				// when stmt declares a local variable (see RearrangeStrategy.create(..)) we need to move all
				// subsequent statements into the then-block to ensure that the existing declared local is visible:
				List<ASTNode> blockStmts= this.block.statements();
				int stmtIdx= blockStmts.indexOf(this.origStmt);
				int lastIdx= blockStmts.size()-1;
				if (stmtIdx != -1 && stmtIdx < lastIdx) {
					thenBlock.statements()
					.add(this.blockRewrite.createMoveTarget(blockStmts.get(stmtIdx+1), blockStmts.get(lastIdx), null, this.group));
				}
				super.insertIfStatement(ifStmt, thenBlock);
			}
		}

		/** Strategy implementation for replacing a single statement with a new block. */
		private static class ReplaceStatement extends RearrangeStrategy {

			final ASTRewrite rewrite;

			ReplaceStatement(Statement origStmt, ASTRewrite rewrite, TextEditGroup group) {
				// did not have a block, create one now to hold new statements:
				super(origStmt, rewrite.getAST().newBlock(), group);
				this.rewrite = rewrite;
			}
			@Override
			public void insertLocalDecl(VariableDeclarationStatement localDecl) {
				this.block.statements().add(localDecl);
			}
			@Override
			public Statement createMoveTargetForOrigStmt() {
				return (Statement) this.rewrite.createMoveTarget(this.origStmt); // group is unused
			}
			@Override
			public void insertIfStatement(IfStatement ifStmt, Block thenBlock) {
				// did not have a block: add if-statement to new block
				this.block.statements().add(ifStmt);
				// and replace the single statement with this block
				this.rewrite.replace(this.origStmt, this.block, this.group);
			}
		}
	}

	private SimpleName fieldReference;
	private CompilationUnit compilationUnit;
	private ASTNode enclosingMethod; // MethodDeclaration or Initializer

	public ExtractToNullCheckedLocalProposal(ICompilationUnit cu, CompilationUnit compilationUnit, SimpleName fieldReference, ASTNode enclosingMethod) {
		super(FixMessages.ExtractToNullCheckedLocalProposal_extractToCheckedLocal_proposalName, cu, null, 100, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE));
		this.compilationUnit= compilationUnit;
		this.fieldReference= fieldReference;
		this.enclosingMethod= enclosingMethod;
	}

	@Override
	protected ASTRewrite getRewrite() throws CoreException {

		// infrastructure:
		AST ast= this.compilationUnit.getAST();
		ASTRewrite rewrite= ASTRewrite.create(ast);
		ImportRewrite imports= ImportRewrite.create(this.compilationUnit, true);
		TextEditGroup group= new TextEditGroup(FixMessages.ExtractToNullCheckedLocalProposal_extractCheckedLocal_editName);
		LinkedProposalPositionGroup localNameGroup= new LinkedProposalPositionGroup(LOCAL_NAME_POSITION_GROUP);
		getLinkedProposalModel().addPositionGroup(localNameGroup);

		// AST context:
		Statement origStmt= ASTNodes.getParent(this.fieldReference, Statement.class);
		// determine suitable strategy for rearranging elements towards a new code structure:
		RearrangeStrategy rearrangeStrategy= RearrangeStrategy.create(origStmt, rewrite, group);

		Expression toReplace;
		ASTNode directParent= this.fieldReference.getParent();
		if (directParent instanceof FieldAccess
				|| (directParent instanceof QualifiedName && this.fieldReference.getLocationInParent() == QualifiedName.NAME_PROPERTY)) {
			toReplace= (Expression) directParent;
		} else {
			toReplace= this.fieldReference;
		}

		// new local declaration initialized from the field reference
		VariableDeclarationFragment localFrag = ast.newVariableDeclarationFragment();
		VariableDeclarationStatement localDecl= ast.newVariableDeclarationStatement(localFrag);
		// ... type
		localDecl.setType(newType(toReplace.resolveTypeBinding(), ast, imports));
		localDecl.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
		// ... name
		String localName= proposeLocalName(this.fieldReference, this.compilationUnit, getCompilationUnit().getJavaProject());
		localFrag.setName(ast.newSimpleName(localName));
		// ... initialization
		localFrag.setInitializer((Expression) ASTNode.copySubtree(ast, toReplace));

		rearrangeStrategy.insertLocalDecl(localDecl);

		// if statement:
		IfStatement ifStmt= ast.newIfStatement();

		// condition:
		InfixExpression nullCheck= ast.newInfixExpression();
		nullCheck.setLeftOperand(ast.newSimpleName(localName));
		nullCheck.setRightOperand(ast.newNullLiteral());
		nullCheck.setOperator(InfixExpression.Operator.NOT_EQUALS);
		ifStmt.setExpression(nullCheck);

		// then block: the original statement
		Block thenBlock = ast.newBlock();
		thenBlock.statements().add(rearrangeStrategy.createMoveTargetForOrigStmt());
		ifStmt.setThenStatement(thenBlock);
		// ... but with the field reference replaced by the new local:
		SimpleName dereferencedName= ast.newSimpleName(localName);
		rewrite.replace(toReplace, dereferencedName, group);


		// else block: a Todo comment
		Block elseBlock = ast.newBlock();
		String elseStatement= "// TODO "+FixMessages.ExtractToNullCheckedLocalProposal_todoHandleNullDescription; //$NON-NLS-1$
		if (origStmt instanceof ReturnStatement) {
			Type returnType= newType(((ReturnStatement)origStmt).getExpression().resolveTypeBinding(), ast, imports);
			ReturnStatement returnStatement= ast.newReturnStatement();
			returnStatement.setExpression(ASTNodeFactory.newDefaultExpression(ast, returnType, 0));
			elseStatement+= '\n' + ASTNodes.asFormattedString(returnStatement, 0, String.valueOf('\n'), FormatterProfileManager.getProjectSettings(getCompilationUnit().getJavaProject()));
		}

		EmptyStatement todoNode= (EmptyStatement) rewrite.createStringPlaceholder(elseStatement, ASTNode.EMPTY_STATEMENT);
		elseBlock.statements().add(todoNode);
		ifStmt.setElseStatement(elseBlock);

		// link all three occurrences of the new local variable:
		addLinkedPosition(rewrite.track(localFrag.getName()), true/*first*/, LOCAL_NAME_POSITION_GROUP);
		addLinkedPosition(rewrite.track(nullCheck.getLeftOperand()), false, LOCAL_NAME_POSITION_GROUP);
		addLinkedPosition(rewrite.track(dereferencedName), false, LOCAL_NAME_POSITION_GROUP);

		rearrangeStrategy.insertIfStatement(ifStmt, thenBlock);

		return rewrite;
	}

	String proposeLocalName(SimpleName fieldName, CompilationUnit root, IJavaProject javaProject) {
		// don't propose names that are already in use:
		Collection<String> variableNames= new ScopeAnalyzer(root).getUsedVariableNames(this.enclosingMethod.getStartPosition(), this.enclosingMethod.getLength());
		String[] names = new String[variableNames.size()+1];
		variableNames.toArray(names);
		// don't propose the field name itself, either:
		String identifier= fieldName.getIdentifier();
		names[names.length-1] = identifier;
		return StubUtility.getLocalNameSuggestions(javaProject, identifier, 0, names)[0];
	}

	/**
	 * Create a fresh type reference
	 * @param typeBinding the type we want to refer to
	 * @param ast AST for creating new nodes
	 * @param imports use this for optimal type names
	 * @return a fully features non-null type reference (can be parameterized and/or array).
	 */
	public static Type newType(ITypeBinding typeBinding, AST ast, ImportRewrite imports) {
		// unwrap array type:
		int dimensions= typeBinding.getDimensions();
		if (dimensions > 0)
			typeBinding= typeBinding.getElementType();

		// unwrap parameterized type:
		ITypeBinding[] typeArguments= typeBinding.getTypeArguments();
		typeBinding= typeBinding.getErasure();

		// create leaf type:
		Type elementType = (typeBinding.isPrimitive())
					? ast.newPrimitiveType(PrimitiveType.toCode(typeBinding.getName()))
					: ast.newSimpleType(ast.newName(imports.addImport(typeBinding)));

		// re-wrap as parameterized type:
		if (typeArguments.length > 0) {
			ParameterizedType parameterizedType= ast.newParameterizedType(elementType);
			for (ITypeBinding typeArgument : typeArguments)
				parameterizedType.typeArguments().add(newType(typeArgument, ast, imports));
			elementType = parameterizedType;
		}

		// re-wrap as array type:
		if (dimensions > 0)
			return ast.newArrayType(elementType, dimensions);
		else
			return elementType;
	}
}