/*******************************************************************************
 * Copyright (c) 2007, 2012 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.ui.text.correction;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;

import org.eclipse.core.resources.IFile;

import org.eclipse.jface.text.IDocument;

import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
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.Expression;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.jdt.internal.corext.refactoring.sef.SelfEncapsulateFieldRefactoring;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;
import org.eclipse.jdt.ui.text.java.IInvocationContext;
import org.eclipse.jdt.ui.text.java.IProblemLocation;
import org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal;
import org.eclipse.jdt.ui.text.java.correction.ChangeCorrectionProposal;
import org.eclipse.jdt.ui.text.java.correction.ICommandAccess;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
import org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter;
import org.eclipse.jdt.internal.ui.refactoring.sef.SelfEncapsulateFieldWizard;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;


public class GetterSetterCorrectionSubProcessor {

	public static final String SELF_ENCAPSULATE_FIELD_ID= "org.eclipse.jdt.ui.correction.encapsulateField.assist"; //$NON-NLS-1$

	private static class ProposalParameter {
		public final boolean useSuper;
		public final ICompilationUnit compilationUnit;
		public final ASTRewrite astRewrite;
		public final Expression accessNode;
		public final Expression qualifier;
		public final IVariableBinding variableBinding;

		public ProposalParameter(boolean useSuper, ICompilationUnit compilationUnit, ASTRewrite rewrite, Expression accessNode, Expression qualifier, IVariableBinding variableBinding) {
			this.useSuper= useSuper;
			this.compilationUnit= compilationUnit;
			this.astRewrite= rewrite;
			this.accessNode= accessNode;
			this.qualifier= qualifier;
			this.variableBinding= variableBinding;
		}
	}

	public static class SelfEncapsulateFieldProposal extends ChangeCorrectionProposal { // public for tests

		private IField fField;
		private boolean fNoDialog;

		public SelfEncapsulateFieldProposal(int relevance, IField field) {
			super(getDescription(field), null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE));
			fField= field;
			fNoDialog= false;
			setCommandId(SELF_ENCAPSULATE_FIELD_ID);
		}

		public IField getField() {
			return fField;
		}

		public void setNoDialog(boolean noDialog) {
			fNoDialog= noDialog;
		}

		public TextFileChange getChange(IFile file) throws CoreException {
			final SelfEncapsulateFieldRefactoring refactoring= new SelfEncapsulateFieldRefactoring(fField);
			refactoring.setVisibility(Flags.AccPublic);
			refactoring.setConsiderVisibility(false);//private field references are just searched in local file
			refactoring.checkInitialConditions(new NullProgressMonitor());
			refactoring.checkFinalConditions(new NullProgressMonitor());
			Change createdChange= refactoring.createChange(new NullProgressMonitor());
			if (createdChange instanceof CompositeChange) {
				Change[] children= ((CompositeChange) createdChange).getChildren();
				for (int i= 0; i < children.length; i++) {
					Change curr= children[i];
					if (curr instanceof TextFileChange && ((TextFileChange) curr).getFile().equals(file)) {
						return (TextFileChange) curr;
					}
				}
			}
			return null;
		}


		private static String getDescription(IField field) {
			return Messages.format(CorrectionMessages.GetterSetterCorrectionSubProcessor_creategetterunsingencapsulatefield_description, BasicElementLabels.getJavaElementName(field.getElementName()));
		}

		/*
		 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension5#getAdditionalProposalInfo(org.eclipse.core.runtime.IProgressMonitor)
		 * @since 3.5
		 */
		@Override
		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
			return CorrectionMessages.GetterSetterCorrectionSubProcessor_additional_info;
		}

		@Override
		public void apply(IDocument document) {
			try {
				final SelfEncapsulateFieldRefactoring refactoring= new SelfEncapsulateFieldRefactoring(fField);
				refactoring.setVisibility(Flags.AccPublic);
				refactoring.setConsiderVisibility(false);//private field references are just searched in local file
				if (fNoDialog) {
					IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
					final RefactoringExecutionHelper helper= new RefactoringExecutionHelper(refactoring, RefactoringStatus.ERROR, RefactoringSaveHelper.SAVE_REFACTORING, JavaPlugin.getActiveWorkbenchShell(), window);
					if (Display.getCurrent() != null) {
						try {
							helper.perform(false, false);
						} catch (InterruptedException e) {
							JavaPlugin.log(e);
						} catch (InvocationTargetException e) {
							JavaPlugin.log(e);
						}
					} else {
						Display.getDefault().syncExec(new Runnable() {
							public void run() {
								try {
									helper.perform(false, false);
								} catch (InterruptedException e) {
									JavaPlugin.log(e);
								} catch (InvocationTargetException e) {
									JavaPlugin.log(e);
								}
							}
						});
					}
				} else {
					new RefactoringStarter().activate(new SelfEncapsulateFieldWizard(refactoring), JavaPlugin.getActiveWorkbenchShell(), "", RefactoringSaveHelper.SAVE_REFACTORING); //$NON-NLS-1$
				}
			} catch (JavaModelException e) {
				ExceptionHandler.handle(e, CorrectionMessages.GetterSetterCorrectionSubProcessor_encapsulate_field_error_title, CorrectionMessages.GetterSetterCorrectionSubProcessor_encapsulate_field_error_message);
			}
		}
	}

	/**
	 * Used by quick assist
	 * @param context the invocation context
	 * @param coveringNode the covering node
	 * @param locations the problems at the corrent location
	 * @param resultingCollections the resulting proposals
	 * @return <code>true</code> if the quick assist is applicable at this offset
	 */
	public static boolean addGetterSetterProposal(IInvocationContext context, ASTNode coveringNode, IProblemLocation[] locations, ArrayList<ICommandAccess> resultingCollections) {
		if (locations != null) {
			for (int i= 0; i < locations.length; i++) {
				int problemId= locations[i].getProblemId();
				if (problemId == IProblem.UnusedPrivateField)
					return false;
				if (problemId == IProblem.UnqualifiedFieldAccess)
					return false;
			}
		}
		return addGetterSetterProposal(context, coveringNode, resultingCollections, 7);
	}

	public static void addGetterSetterProposal(IInvocationContext context, IProblemLocation location, Collection<ICommandAccess> proposals, int relevance) {
		addGetterSetterProposal(context, location.getCoveringNode(context.getASTRoot()), proposals, relevance);
	}

	private static boolean addGetterSetterProposal(IInvocationContext context, ASTNode coveringNode, Collection<ICommandAccess> proposals, int relevance) {
		if (!(coveringNode instanceof SimpleName)) {
			return false;
		}
		SimpleName sn= (SimpleName) coveringNode;

		IBinding binding= sn.resolveBinding();
		if (!(binding instanceof IVariableBinding))
			return false;
		IVariableBinding variableBinding= (IVariableBinding) binding;
		if (!variableBinding.isField())
			return false;

		if (proposals == null)
			return true;

		ChangeCorrectionProposal proposal= getProposal(context.getCompilationUnit(), sn, variableBinding, relevance);
		if (proposal != null)
			proposals.add(proposal);
		return true;
	}

	private static ChangeCorrectionProposal getProposal(ICompilationUnit cu, SimpleName sn, IVariableBinding variableBinding, int relevance) {
		Expression accessNode= sn;
		Expression qualifier= null;
		boolean useSuper= false;

		ASTNode parent= sn.getParent();
		switch (parent.getNodeType()) {
			case ASTNode.QUALIFIED_NAME:
				accessNode= (Expression) parent;
				qualifier= ((QualifiedName) parent).getQualifier();
				break;
			case ASTNode.SUPER_FIELD_ACCESS:
				accessNode= (Expression) parent;
				qualifier= ((SuperFieldAccess) parent).getQualifier();
				useSuper= true;
				break;
		}
		ASTRewrite rewrite= ASTRewrite.create(sn.getAST());
		ProposalParameter gspc= new ProposalParameter(useSuper, cu, rewrite, accessNode, qualifier, variableBinding);
		if (ASTResolving.isWriteAccess(sn))
			return addSetterProposal(gspc, relevance);
		else
			return addGetterProposal(gspc, relevance);
	}

	/**
	 * Proposes a getter for this field.
	 * 
	 * @param context the proposal parameter
	 * @param relevance relevance of this proposal
	 * @return the proposal if available or null
	 */
	private static ChangeCorrectionProposal addGetterProposal(ProposalParameter context, int relevance) {
		IMethodBinding method= findGetter(context);
		if (method != null) {
			Expression mi= createMethodInvocation(context, method, null);
			context.astRewrite.replace(context.accessNode, mi, null);

			String label= Messages.format(CorrectionMessages.GetterSetterCorrectionSubProcessor_replacewithgetter_description, BasicElementLabels.getJavaCodeString(ASTNodes.asString(context.accessNode)));
			Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
			ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image);
			return proposal;
		} else {
			IJavaElement element= context.variableBinding.getJavaElement();
			if (element instanceof IField) {
				IField field= (IField) element;
				try {
					if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field))
						return new SelfEncapsulateFieldProposal(relevance, field);
				} catch (JavaModelException e) {
					JavaPlugin.log(e);
				}
			}
		}
		return null;
	}

	private static IMethodBinding findGetter(ProposalParameter context) {
		ITypeBinding returnType= context.variableBinding.getType();
		String getterName= GetterSetterUtil.getGetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean(context));
		ITypeBinding declaringType= context.variableBinding.getDeclaringClass();
		if (declaringType == null)
			return null;
		IMethodBinding getter= Bindings.findMethodInHierarchy(declaringType, getterName, new ITypeBinding[0]);
		if (getter != null && getter.getReturnType().isAssignmentCompatible(returnType) && Modifier.isStatic(getter.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers()))
			return getter;
		return null;
	}

	private static Expression createMethodInvocation(ProposalParameter context, IMethodBinding method, Expression argument) {
		AST ast= context.astRewrite.getAST();
		Expression qualifier= context.qualifier;
		if (context.useSuper) {
			SuperMethodInvocation invocation= ast.newSuperMethodInvocation();
			invocation.setName(ast.newSimpleName(method.getName()));
			if (qualifier != null)
				invocation.setQualifier((Name) context.astRewrite.createCopyTarget(qualifier));
			if (argument != null)
				invocation.arguments().add(argument);
			return invocation;
		} else {
			MethodInvocation invocation= ast.newMethodInvocation();
			invocation.setName(ast.newSimpleName(method.getName()));
			if (qualifier != null)
				invocation.setExpression((Expression) context.astRewrite.createCopyTarget(qualifier));
			if (argument != null)
				invocation.arguments().add(argument);
			return invocation;
		}
	}

	/**
	 * Proposes a setter for this field.
	 * 
	 * @param context the proposal parameter
	 * @param relevance relevance of this proposal
	 * @return the proposal if available or null
	 */
	private static ChangeCorrectionProposal addSetterProposal(ProposalParameter context, int relevance) {
		boolean isBoolean= isBoolean(context);
		String setterName= GetterSetterUtil.getSetterName(context.variableBinding, context.compilationUnit.getJavaProject(), null, isBoolean);
		ITypeBinding declaringType= context.variableBinding.getDeclaringClass();
		if (declaringType == null)
			return null;

		IMethodBinding method= Bindings.findMethodInHierarchy(declaringType, setterName, new ITypeBinding[] { context.variableBinding.getType() });
		if (method != null && Bindings.isVoidType(method.getReturnType()) && (Modifier.isStatic(method.getModifiers()) == Modifier.isStatic(context.variableBinding.getModifiers()))) {
			Expression assignedValue= getAssignedValue(context);
			if (assignedValue == null)
				return null; //we don't know how to handle those cases.
			Expression mi= createMethodInvocation(context, method, assignedValue);
			context.astRewrite.replace(context.accessNode.getParent(), mi, null);

			String label= Messages.format(CorrectionMessages.GetterSetterCorrectionSubProcessor_replacewithsetter_description, BasicElementLabels.getJavaCodeString(ASTNodes.asString(context.accessNode)));
			Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
			ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.compilationUnit, context.astRewrite, relevance, image);
			return proposal;
		} else {
			IJavaElement element= context.variableBinding.getJavaElement();
			if (element instanceof IField) {
				IField field= (IField) element;
				try {
					if (RefactoringAvailabilityTester.isSelfEncapsulateAvailable(field))
						return new SelfEncapsulateFieldProposal(relevance, field);
				} catch (JavaModelException e) {
					JavaPlugin.log(e);
				}
			}
		}
		return null;
	}

	private static boolean isBoolean(ProposalParameter context) {
		AST ast= context.astRewrite.getAST();
		boolean isBoolean= ast.resolveWellKnownType("boolean") == context.variableBinding.getType(); //$NON-NLS-1$
		if (!isBoolean)
			isBoolean= ast.resolveWellKnownType("java.lang.Boolean") == context.variableBinding.getType(); //$NON-NLS-1$
		return isBoolean;
	}

	private static Expression getAssignedValue(ProposalParameter context) {
		ASTNode parent= context.accessNode.getParent();
		ASTRewrite astRewrite= context.astRewrite;
		IJavaProject javaProject= context.compilationUnit.getJavaProject();
		IMethodBinding getter= findGetter(context);
		Expression getterExpression= null;
		if (getter != null) {
			getterExpression= astRewrite.getAST().newSimpleName("placeholder"); //$NON-NLS-1$
		}
		ITypeBinding type= context.variableBinding.getType();
		boolean is50OrHigher= JavaModelUtil.is50OrHigher(javaProject);
		Expression result= GetterSetterUtil.getAssignedValue(parent, astRewrite, getterExpression, type, is50OrHigher);
		if (result != null && getterExpression != null && getterExpression.getParent() != null) {
			getterExpression.getParent().setStructuralProperty(getterExpression.getLocationInParent(), createMethodInvocation(context, getter, null));
		}
		return result;
	}

}
