/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Stephan Herrmann - Contribution for Bug 463360 - [override method][null] generating method override should not create redundant null annotations
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.text.java;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.graphics.Image;

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

import org.eclipse.text.edits.MalformedTreeException;

import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.window.Window;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.link.LinkedModeModel;

import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;

import org.eclipse.jdt.internal.core.manipulation.util.Strings;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;

import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.dialogs.OverrideMethodDialog;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.jdt.internal.ui.preferences.formatter.FormatterProfileManager;


public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal implements ICompletionProposalExtension4 {

	private final String fDeclarationSignature;
	private final IType fSuperType;

	private boolean fIsContextInformationComputed;
	private int fContextInformationPosition;

	private ImportRewrite fImportRewrite;


	public AnonymousTypeCompletionProposal(IJavaProject jproject, ICompilationUnit cu, JavaContentAssistInvocationContext invocationContext, int start, int length, String constructorCompletion, StyledString displayName, String declarationSignature, IType superType, int relevance) {
		super(constructorCompletion, cu, start, length, null, displayName, relevance, null, invocationContext);
		Assert.isNotNull(declarationSignature);
		Assert.isNotNull(jproject);
		Assert.isNotNull(cu);
		Assert.isNotNull(superType);

		fDeclarationSignature= declarationSignature;
		fSuperType= superType;

		setCursorPosition(constructorCompletion.indexOf('(') + 1);
	}

	private String createDummyType(String name) throws JavaModelException {
		StringBuffer buffer= new StringBuffer();

		buffer.append("abstract class "); //$NON-NLS-1$
		buffer.append(name);
		if (fSuperType.isInterface())
			buffer.append(" implements "); //$NON-NLS-1$
		else
			buffer.append(" extends "); //$NON-NLS-1$

		if (fDeclarationSignature != null)
			buffer.append(Signature.toString(fDeclarationSignature));
		else
			buffer.append(fSuperType.getFullyQualifiedParameterizedName());
		buffer.append(" {"); //$NON-NLS-1$
		buffer.append("\n"); // Using newline is ok since source is used in dummy compilation unit //$NON-NLS-1$
		buffer.append("}"); //$NON-NLS-1$
		return buffer.toString();
	}

	private String createNewBody(ImportRewrite importRewrite, int offset) throws CoreException {
		if (importRewrite == null)
			return null;

		ICompilationUnit workingCopy= null;
		try {
			String name= "Type" + System.currentTimeMillis(); //$NON-NLS-1$
			workingCopy= fCompilationUnit.getPrimary().getWorkingCopy(null);


			ISourceRange range= fSuperType.getSourceRange();
			boolean sameUnit= range != null && fCompilationUnit.equals(fSuperType.getCompilationUnit());

			// creates a type that extends the super type
			String dummyClassContent= createDummyType(name);

			StringBuffer workingCopyContents= new StringBuffer(fCompilationUnit.getSource());
			int insertPosition;
			if (sameUnit) {
				insertPosition= range.getOffset() + range.getLength();
			} else {
				ISourceRange firstTypeRange= fCompilationUnit.getTypes()[0].getSourceRange();
				insertPosition= firstTypeRange.getOffset();
			}
			if (fSuperType.isLocal()) {
				// add an extra block: helps the AST to recover
				workingCopyContents.insert(insertPosition, '{' + dummyClassContent + '}');
				insertPosition++;
				if(offset > insertPosition) {
					offset += dummyClassContent.length()+2;
				}
			} else {
				/*
				 * The two empty lines are added because the trackedDeclaration uses the covered range
				 * and hence would also included comments that directly follow the dummy class.
				 */
				workingCopyContents.insert(insertPosition, dummyClassContent + "\n\n"); //$NON-NLS-1$
				if(offset > insertPosition) {
					offset += dummyClassContent.length()+2;
				}
			}

			workingCopy.getBuffer().setContents(workingCopyContents.toString());

			ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
			parser.setResolveBindings(true);
			parser.setStatementsRecovery(true);
			parser.setSource(workingCopy);

			CompilationUnit astRoot= (CompilationUnit) parser.createAST(new NullProgressMonitor());
			ImportRewriteContext context=new ContextSensitiveImportRewriteContext(astRoot, offset, importRewrite);
			ASTNode newType= NodeFinder.perform(astRoot, insertPosition, dummyClassContent.length());
			if (!(newType instanceof AbstractTypeDeclaration))
				return null;

			AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) newType;
			ITypeBinding dummyTypeBinding= declaration.resolveBinding();
			if (dummyTypeBinding == null)
				return null;

			IMethodBinding[] bindings= StubUtility2.getOverridableMethods(astRoot.getAST(), dummyTypeBinding, true);
			
			if (fSuperType.isInterface()) {
				ITypeBinding[] dummySuperInterfaces= dummyTypeBinding.getInterfaces();
				if (dummySuperInterfaces.length == 0 || dummySuperInterfaces.length == 1 && dummySuperInterfaces[0].isRawType())
					bindings= new IMethodBinding[0];
			} else {
				ITypeBinding dummySuperclass= dummyTypeBinding.getSuperclass();
				if (dummySuperclass == null || dummySuperclass.isRawType())
					bindings= new IMethodBinding[0];
			}
			
			CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(fSuperType.getJavaProject());

			IMethodBinding[] methodsToOverride= null;

			IType type= null;
			if (!fSuperType.isInterface() && !fSuperType.isAnnotation()) {
				IJavaElement typeElement= dummyTypeBinding.getJavaElement();
				// add extra checks here as the recovered code is fragile
				if (typeElement instanceof IType && name.equals(typeElement.getElementName()) && typeElement.exists()) {
					type= (IType) typeElement;
				}
			}

			if (type != null) {
				OverrideMethodDialog dialog= new OverrideMethodDialog(JavaPlugin.getActiveWorkbenchShell(), null, type, true);
				dialog.setGenerateComment(false);
				dialog.setElementPositionEnabled(false);
				if (dialog.open() == Window.OK) {
					Object[] selection= dialog.getResult();
					ArrayList<Object> result= new ArrayList<>(selection.length);
					for (int i= 0; i < selection.length; i++) {
						if (selection[i] instanceof IMethodBinding)
							result.add(selection[i]);
					}
					methodsToOverride= result.toArray(new IMethodBinding[result.size()]);
					settings.createComments= dialog.getGenerateComment();
				} else {
					// cancelled
					setReplacementString(""); //$NON-NLS-1$
					setReplacementLength(0);
					return null;
				}
			} else {
				settings.createComments= false;
				List<IMethodBinding> result= new ArrayList<>();
				for (int i= 0; i < bindings.length; i++) {
					IMethodBinding curr= bindings[i];
					if (Modifier.isAbstract(curr.getModifiers()))
						result.add(curr);
				}
				methodsToOverride= result.toArray(new IMethodBinding[result.size()]);
			}
			ASTNode focusNode; // used to find @NonNullByDefault effective
			if (fCompilationUnit.getJavaProject().getOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, true).equals(JavaCore.ENABLED)) {
				focusNode= NodeFinder.perform(astRoot, getReplacementOffset()+dummyClassContent.length(), 0);
			} else {
				focusNode= null;
			}
			ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
			ITrackedNodePosition trackedDeclaration= rewrite.track(declaration);

			ListRewrite rewriter= rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
			for (int i= 0; i < methodsToOverride.length; i++) {
				IMethodBinding curr= methodsToOverride[i];
				MethodDeclaration stub= StubUtility2.createImplementationStub(workingCopy, rewrite, importRewrite, context, curr, dummyTypeBinding, settings, dummyTypeBinding.isInterface(), focusNode);
				rewriter.insertFirst(stub, null);
			}


			IDocument document= new Document(workingCopy.getSource());
			try {
				rewrite.rewriteAST().apply(document);

				int bodyStart= trackedDeclaration.getStartPosition() + dummyClassContent.indexOf('{');
				int bodyEnd= trackedDeclaration.getStartPosition() + trackedDeclaration.getLength();
				return document.get(bodyStart, bodyEnd - bodyStart);
			} catch (MalformedTreeException exception) {
				JavaPlugin.log(exception);
			} catch (BadLocationException exception) {
				JavaPlugin.log(exception);
			}
			return null;
		} finally {
			if (workingCopy != null)
				workingCopy.discardWorkingCopy();
		}
	}

	protected Image getImageForType(IType type) {
		String imageName= JavaPluginImages.IMG_OBJS_CLASS; // default
		try {
			if (type.isAnnotation()) {
				imageName= JavaPluginImages.IMG_OBJS_ANNOTATION;
			} else if (type.isInterface()) {
				imageName= JavaPluginImages.IMG_OBJS_INTERFACE;
			}
		} catch (JavaModelException e) {
			JavaPlugin.log(e);
		}
		return JavaPluginImages.get(imageName);
	}

	@Override
	public Image getImage() {
		Image image= super.getImage();
		if (image == null) {
			image= getImageForType(fSuperType);
			setImage(image);
		}
		return image;
	}

	/*
	 * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable()
	 */
	@Override
	public boolean isAutoInsertable() {
		return false;
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#isOffsetValid(int)
	 * @since 3.5
	 */
	@Override
	protected boolean isOffsetValid(int offset) {
		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		if (coreProposal.getKind() != CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION)
			return super.isOffsetValid(offset);

		return coreProposal.getRequiredProposals()[0].getReplaceStart() <= offset;
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#getPrefixCompletionStart(org.eclipse.jface.text.IDocument, int)
	 * @since 3.5
	 */
	@Override
	public int getPrefixCompletionStart(IDocument document, int completionOffset) {
		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		if (coreProposal.getKind() != CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION)
			return super.getPrefixCompletionStart(document, completionOffset);

		return coreProposal.getRequiredProposals()[0].getReplaceStart();
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposal#getPrefixCompletionText(org.eclipse.jface.text.IDocument, int)
	 * @since 3.5
	 */
	@Override
	public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		if (coreProposal.getKind() != CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION)
			return super.getPrefixCompletionText(document, completionOffset);

		return String.valueOf(coreProposal.getName());
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#getPrefix(org.eclipse.jface.text.IDocument, int)
	 * @since 3.5
	 */
	@Override
	protected String getPrefix(IDocument document, int offset) {
		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		if (coreProposal.getKind() != CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION)
			return super.getPrefix(document, offset);

		int replacementOffset= coreProposal.getRequiredProposals()[0].getReplaceStart();

		try {
			int length= offset - replacementOffset;
			if (length > 0)
				return document.get(replacementOffset, length);
		} catch (BadLocationException x) {
		}
		return ""; //$NON-NLS-1$

	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposal#isValidPrefix(java.lang.String)
	 * @since 3.5
	 */
	@Override
	protected boolean isValidPrefix(String prefix) {
		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		if (coreProposal.getKind() != CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION)
			return super.isValidPrefix(prefix);

		return super.isValidPrefix(prefix) || isPrefix(prefix, String.valueOf(coreProposal.getName()));
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposal#apply(org.eclipse.jface.text.IDocument, char, int)
	 * @since 3.5
	 */
	@Override
	public void apply(IDocument document, char trigger, int offset) {
		super.apply(document, trigger, offset);
		LinkedModeModel.closeAllModels(document);
	}


	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposal#updateReplacementString(org.eclipse.jface.text.IDocument, char, int, org.eclipse.jdt.core.dom.rewrite.ImportRewrite)
	 */
	@Override
	protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException {
		fImportRewrite= impRewrite;
		String newBody= createNewBody(impRewrite, offset);
		if (newBody == null)
			return false;

		CompletionProposal coreProposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		boolean isAnonymousConstructorInvoc= coreProposal.getKind() == CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION;

		boolean replacementStringEndsWithParentheses= isAnonymousConstructorInvoc || getReplacementString().endsWith(")"); //$NON-NLS-1$

		// construct replacement text: an expression to be formatted
		StringBuffer buf= new StringBuffer("new A("); //$NON-NLS-1$
		if (!replacementStringEndsWithParentheses || isAnonymousConstructorInvoc)
			buf.append(')');
		buf.append(newBody);

		// use the code formatter
		String lineDelim= TextUtilities.getDefaultLineDelimiter(document);
		final IJavaProject project= fCompilationUnit.getJavaProject();
		IRegion lineInfo= document.getLineInformationOfOffset(getReplacementOffset());
		int indent= Strings.computeIndentUnits(document.get(lineInfo.getOffset(), lineInfo.getLength()), project);

		Map<String, String> options= project != null ? FormatterProfileManager.getProjectSettings(project) : JavaCore.getOptions();
		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES, DefaultCodeFormatterConstants.TRUE);
		String replacementString= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, buf.toString(), 0, lineDelim, options);

		int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength();

		int p= offset;
		char ch= document.getChar(p);
		while (p < lineEndOffset) {
			if (ch == '(' || ch == ')' || ch == ';' || ch == ',')
				break;
			ch= document.getChar(++p);
		}

		if (ch != ';' && ch != ',' && ch != ')')
			replacementString= replacementString + ';';

		replacementString= Strings.changeIndent(replacementString, 0, project, CodeFormatterUtil.createIndentString(indent, project), lineDelim);
		
		int beginIndex= replacementString.indexOf('(');
		if (!isAnonymousConstructorInvoc)
			beginIndex++;
		replacementString= replacementString.substring(beginIndex);

		int pos= offset;
		if (isAnonymousConstructorInvoc && (insertCompletion() ^ isInsertModeToggled())) {
			// Keep existing code
			int endPos= pos;
			ch= document.getChar(endPos);
			while (endPos < lineEndOffset && ch != '(' && ch != ')' && ch != ';' && ch != ',' && !Character.isWhitespace(ch))
				ch= document.getChar(++endPos);

			int keepLength= endPos - pos;
			if (keepLength > 0) {
				String keepStr= document.get(pos, keepLength);
				replacementString= replacementString + keepStr;
				setCursorPosition(replacementString.length() - keepLength);
			}
		} else
			setCursorPosition(replacementString.length());
		
		setReplacementString(replacementString);

		if (pos < document.getLength() && document.getChar(pos) == ')') {
			int currentLength= getReplacementLength();
			if (replacementStringEndsWithParentheses)
				setReplacementLength(currentLength + pos - offset);
			else
				setReplacementLength(currentLength + pos - offset + 1);
		}
		return false;
	}

	/*
	 * @see ICompletionProposalExtension#getContextInformationPosition()
	 * @since 3.4
	 */
	@Override
	public int getContextInformationPosition() {
		if (!fIsContextInformationComputed)
			setContextInformation(computeContextInformation());
		return fContextInformationPosition;
	}


	/*
	 * @see ICompletionProposal#getContextInformation()
	 * @since 3.4
	 */
	@Override
	public final IContextInformation getContextInformation() {
		if (!fIsContextInformationComputed)
			setContextInformation(computeContextInformation());
		return super.getContextInformation();
	}

	protected IContextInformation computeContextInformation() {
		try {
			fContextInformationPosition= getReplacementOffset() - 1;

			CompletionProposal proposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
			// no context information for METHOD_NAME_REF proposals (e.g. for static imports)
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=94654
			if (hasParameters() && (getReplacementString().endsWith(")") || getReplacementString().length() == 0)) { //$NON-NLS-1$
				ProposalContextInformation contextInformation= new ProposalContextInformation(proposal);
				fContextInformationPosition= getReplacementOffset() + getCursorPosition();
				if (fContextInformationPosition != 0 && proposal.getCompletion().length == 0)
					contextInformation.setContextInformationPosition(fContextInformationPosition);
				return contextInformation;
			}
			return null;
		} finally {
			fIsContextInformationComputed= true;
		}
	}

	/**
	 * Returns <code>true</code> if the method being inserted has at least one parameter. Note
	 * that this does not say anything about whether the argument list should be inserted.
	 *
	 * @return <code>true</code> if the method has any parameters, <code>false</code> if it has no parameters
	 * @since 3.4
	 */
	private boolean hasParameters() {
		CompletionProposal proposal= ((MemberProposalInfo)getProposalInfo()).fProposal;
		return Signature.getParameterCount(proposal.getSignature()) > 0;
	}

	/*
	 * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#createLazyJavaTypeCompletionProposal(org.eclipse.jdt.core.CompletionProposal, org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext)
	 * @since 3.5
	 */
	@Override
	protected LazyJavaCompletionProposal createRequiredTypeCompletionProposal(CompletionProposal completionProposal, JavaContentAssistInvocationContext invocationContext) {
		LazyJavaCompletionProposal proposal= super.createRequiredTypeCompletionProposal(completionProposal, invocationContext);
		if (proposal instanceof LazyJavaTypeCompletionProposal)
			((LazyJavaTypeCompletionProposal)proposal).setImportRewrite(fImportRewrite);
		return proposal;
	}

}