/*******************************************************************************
 * Copyright (c) 2011, 2016 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.ui.propertiesfileeditor;

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

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;

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

import org.eclipse.core.resources.IFile;

import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPartitioningException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
import org.eclipse.jface.text.source.ISourceViewer;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.TextChange;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter;
import org.eclipse.jdt.internal.corext.refactoring.nls.AccessorClassModifier;
import org.eclipse.jdt.internal.corext.refactoring.nls.NLSPropertyFileModifier;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
import org.eclipse.jdt.ui.text.java.correction.CUCorrectionProposal;
import org.eclipse.jdt.ui.text.java.correction.ChangeCorrectionProposal;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.text.correction.proposals.EditAnnotator;

/**
 * The properties file quick assist processor.
 *
 * @since 3.8
 */
public class PropertiesQuickAssistProcessor {

	public static boolean hasAssists(PropertiesAssistContext invocationContext) {
		try {
			return getEscapeUnescapeBackslashProposals(invocationContext, null) ||
					getCreateFieldsInAccessorClassProposals(invocationContext, null) ||
					getRemovePropertiesProposals(invocationContext, null) ||
					getRenameKeysProposals(invocationContext, null);
		} catch (BadLocationException | BadPartitioningException e) {
			JavaPlugin.log(e);
		}
		return false;
	}

	public static ICompletionProposal[] collectAssists(PropertiesAssistContext invocationContext) throws BadLocationException, BadPartitioningException {
		ArrayList<ICompletionProposal> resultingCollections= new ArrayList<>();

		getEscapeUnescapeBackslashProposals(invocationContext, resultingCollections);
		getCreateFieldsInAccessorClassProposals(invocationContext, resultingCollections);
		getRemovePropertiesProposals(invocationContext, resultingCollections);
		getRenameKeysProposals(invocationContext, resultingCollections);

		if (resultingCollections.isEmpty())
			return null;
		return resultingCollections.toArray(new ICompletionProposal[resultingCollections.size()]);
	}

	private static boolean getEscapeUnescapeBackslashProposals(IQuickAssistInvocationContext invocationContext, ArrayList<ICompletionProposal> resultingCollections) throws BadLocationException,
			BadPartitioningException {
		ISourceViewer sourceViewer= invocationContext.getSourceViewer();
		IDocument document= sourceViewer.getDocument();
		Point selectedRange= sourceViewer.getSelectedRange();
		int selectionOffset= selectedRange.x;
		int selectionLength= selectedRange.y;
		int proposalOffset;
		int proposalLength;
		String text;
		if (selectionLength == 0) {
			if (selectionOffset != document.getLength()) {
				char ch= document.getChar(selectionOffset);
				if (ch == '=' || ch == ':') { //see PropertiesFilePartitionScanner()
					return false;
				}
			}

			ITypedRegion partition= null;
			if (document instanceof IDocumentExtension3)
				partition= ((IDocumentExtension3)document).getPartition(IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING, invocationContext.getOffset(), false);
			if (partition == null)
				return false;

			String type= partition.getType();
			if (!type.equals(IPropertiesFilePartitions.PROPERTY_VALUE)
					&& !type.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
				return false;
			}
			proposalOffset= partition.getOffset();
			proposalLength= partition.getLength();
			text= document.get(proposalOffset, proposalLength);

			if (type.equals(IPropertiesFilePartitions.PROPERTY_VALUE)) {
				text= text.substring(1); //see PropertiesFilePartitionScanner()
				proposalOffset++;
				proposalLength--;
			}
		} else {
			proposalOffset= selectionOffset;
			proposalLength= selectionLength;
			text= document.get(proposalOffset, proposalLength);
		}

		if (PropertiesFileEscapes.containsUnescapedBackslash(text)) {
			if (resultingCollections == null)
				return true;
			resultingCollections.add(new EscapeBackslashCompletionProposal(PropertiesFileEscapes.escape(text, false, true, false), proposalOffset, proposalLength,
					PropertiesFileEditorMessages.EscapeBackslashCompletionProposal_escapeBackslashes));
			return true;
		}
		if (PropertiesFileEscapes.containsEscapedBackslashes(text)) {
			if (resultingCollections == null)
				return true;
			resultingCollections.add(new EscapeBackslashCompletionProposal(PropertiesFileEscapes.unescapeBackslashes(text), proposalOffset, proposalLength,
					PropertiesFileEditorMessages.EscapeBackslashCompletionProposal_unescapeBackslashes));
			return true;
		}
		return false;
	}

	private static boolean getCreateFieldsInAccessorClassProposals(PropertiesAssistContext invocationContext, ArrayList<ICompletionProposal> resultingCollections)
			throws BadLocationException, BadPartitioningException {
		IDocument document= invocationContext.getDocument();
		int selectionOffset= invocationContext.getOffset();
		int selectionLength= invocationContext.getLength();
		List<String> fields= new ArrayList<>();

		IType accessorClass= invocationContext.getAccessorType();
		if (accessorClass == null || !isEclipseNLSUsed(accessorClass))
			return false;

		List<String> keys= getKeysFromSelection(document, selectionOffset, selectionLength);
		if (keys == null || keys.isEmpty())
			return false;

		for (String key : keys) {
			if (!isValidJavaIdentifier(key))
				continue;
			IField field= accessorClass.getField(key);
			if (field.exists())
				continue;
			if (resultingCollections == null)
				return true;
			fields.add(key);
		}

		if (fields.isEmpty())
			return false;

		ICompilationUnit cu= accessorClass.getCompilationUnit();
		try {
			Change change= AccessorClassModifier.addFields(cu, fields);
			String name= Messages.format(fields.size() == 1 ? PropertiesFileEditorMessages.PropertiesCorrectionProcessor_create_field_in_accessor_label : PropertiesFileEditorMessages.PropertiesCorrectionProcessor_create_fields_in_accessor_label, BasicElementLabels.getFileName(cu));
			resultingCollections.add(new CUCorrectionProposal(name, cu, (TextChange) change, 5, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE)));
		} catch (CoreException e) {
			JavaPlugin.log(e);
			return false;
		}
		return true;
	}

	private static boolean isValidJavaIdentifier(String key) {
		if (!Character.isJavaIdentifierStart(key.charAt(0)))
			return false;

		for (int i= 1, length= key.length(); i < length; i++) {
			if (!Character.isJavaIdentifierPart(key.charAt(i)))
				return false;
		}
		return true;
	}

	private static boolean getRemovePropertiesProposals(PropertiesAssistContext invocationContext, ArrayList<ICompletionProposal> resultingCollections)
			throws BadLocationException, BadPartitioningException {
		IDocument document= invocationContext.getDocument();
		int selectionOffset= invocationContext.getOffset();
		int selectionLength= invocationContext.getLength();
		List<String> fields= new ArrayList<>();

		IFile file= invocationContext.getFile();
		if (file == null)
			return false;

		IType accessorClass= invocationContext.getAccessorType();
		if (accessorClass == null || !isEclipseNLSUsed(accessorClass))
			return false;

		List<String> keys= getKeysFromSelection(document, selectionOffset, selectionLength);
		if (keys == null || keys.isEmpty())
			return false;
		if (resultingCollections == null)
			return true;

		for (String key : keys) {
			IField field= accessorClass.getField(key);
			if (field.exists())
				fields.add(key);
		}

		ICompilationUnit cu= accessorClass.getCompilationUnit();
		try {
			Change propertiesFileChange= NLSPropertyFileModifier.removeKeys(file.getFullPath(), keys);
			Change[] changes;
			if (fields.size() > 0) {
				Change accessorChange= AccessorClassModifier.removeFields(cu, fields);
				changes= new Change[] { propertiesFileChange, accessorChange };
			} else {
				changes= new Change[] { propertiesFileChange };
			}

			String name= (keys.size() == 1)
					? PropertiesFileEditorMessages.PropertiesCorrectionProcessor_remove_property_label
					: PropertiesFileEditorMessages.PropertiesCorrectionProcessor_remove_properties_label;
			resultingCollections.add(new RemovePropertiesProposal(name, 4, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE), changes));
		} catch (CoreException e) {
			JavaPlugin.log(e);
			return false;
		}
		return true;
	}

	private static boolean getRenameKeysProposals(PropertiesAssistContext invocationContext, ArrayList<ICompletionProposal> resultingCollections)
			throws BadLocationException, BadPartitioningException {
		ISourceViewer sourceViewer= invocationContext.getSourceViewer();
		IDocument document= invocationContext.getDocument();
		int selectionOffset= invocationContext.getOffset();
		int selectionLength= invocationContext.getLength();
		IField field= null;

		IType accessorClass= invocationContext.getAccessorType();
		if (accessorClass == null || !isEclipseNLSUsed(accessorClass))
			return false;

		List<String> keys= getKeysFromSelection(document, selectionOffset, selectionLength);
		if (keys == null || keys.size() != 1)
			return false;

		field= accessorClass.getField(keys.get(0));
		if (!field.exists())
			return false;
		if (resultingCollections == null)
			return true;

		String name= PropertiesFileEditorMessages.PropertiesCorrectionProcessor_rename_in_workspace;
		resultingCollections.add(new RenameKeyProposal(name, 5, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE), field, sourceViewer.getTextWidget().getShell()));
		return true;
	}

	private static boolean isEclipseNLSUsed(IType accessor) {
		IJavaProject javaProject= accessor.getJavaProject();
		if (javaProject == null || !javaProject.exists())
			return false;

		try {
			IType nls= javaProject.findType("org.eclipse.osgi.util.NLS"); //$NON-NLS-1$
			if(nls==null)
				return false;
			ITypeHierarchy supertypeHierarchy= accessor.newSupertypeHierarchy(null);
			return supertypeHierarchy.contains(nls);
		} catch (JavaModelException e) {
			return false;
		}
	}

	private static List<String> getKeysFromSelection(IDocument document, int selectionOffset, int selectionLength) throws BadLocationException,
			BadPartitioningException {
		List<String> keys= new ArrayList<>();
		String selection= document.get(selectionOffset, (selectionLength == 0) ? 1 : selectionLength).trim();
		if (selection.length() == 0)
			return null;
		if (selectionLength == 0) {
			ITypedRegion partition= null;
			if (document instanceof IDocumentExtension3)
				partition= ((IDocumentExtension3) document).getPartition(IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING, selectionOffset, false);
			if (partition == null)
				return null;

			String type= partition.getType();
			if (!(type.equals(IDocument.DEFAULT_CONTENT_TYPE))) {
				return null;
			}
			String key= document.get(partition.getOffset(), partition.getLength()).trim();
			if (key.length() > 0)
				keys.add(key);
		} else {
			int offset= selectionOffset;
			int endOffset= selectionOffset + selectionLength;

			while (offset < endOffset) {
				ITypedRegion partition= null;
				if (document instanceof IDocumentExtension3)
					partition= ((IDocumentExtension3) document).getPartition(IPropertiesFilePartitions.PROPERTIES_FILE_PARTITIONING, offset, false);
				if (partition == null)
					return null;

				int partitionOffset= partition.getOffset();
				int partitionLength= partition.getLength();
				offset= partitionOffset + partitionLength;

				String type= partition.getType();
				if (!(type.equals(IDocument.DEFAULT_CONTENT_TYPE))) {
					continue;
				}
				String key= document.get(partitionOffset, partitionLength).trim();
				if (key.length() > 0)
					keys.add(key);
			}
		}
		return keys;
	}

	private static class RemovePropertiesProposal extends ChangeCorrectionProposal {

		private final Change[] fChanges;

		protected RemovePropertiesProposal(String name, int relevance, Image image, Change[] changes) {
			super(name, null, relevance, image);
			fChanges= changes;
		}

		@Override
		protected Change createChange() throws CoreException {
			return new CompositeChange(getName(), fChanges);
		}

		@Override
		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
			final StringBuffer buf= new StringBuffer();

			try {
				for (Change fChange : fChanges) {
					if (fChange instanceof TextChange) {
						TextChange change= (TextChange) fChange;
						String filename= getFileName(change);
						if (filename != null) {
							buf.append("<b>"); //$NON-NLS-1$
							buf.append(filename);
							buf.append("</b>"); //$NON-NLS-1$
							buf.append("<br>"); //$NON-NLS-1$
						}
						change.setKeepPreviewEdits(true);
						IDocument currentContent= change.getCurrentDocument(monitor);
						TextEdit rootEdit= change.getEdit();
						EditAnnotator ea= new EditAnnotator(buf, currentContent) {
							@Override
							protected boolean rangeRemoved(TextEdit edit) {
								return annotateEdit(edit, "<del>", "</del>"); //$NON-NLS-1$ //$NON-NLS-2$
							}
						};
						rootEdit.accept(ea);
						ea.unchangedUntil(currentContent.getLength()); // Final pre-existing region
						buf.append("<br><br>"); //$NON-NLS-1$
					}
				}

			} catch (CoreException e) {
				JavaPlugin.log(e);
			}
			return buf.toString();
		}

		private String getFileName(TextChange change) {
			Object modifiedElement= change.getModifiedElement();
			if (modifiedElement instanceof IFile) {
				return ((IFile) modifiedElement).getName();
			} else if (modifiedElement instanceof ICompilationUnit) {
				return ((ICompilationUnit) modifiedElement).getElementName();
			}
			return null;
		}
	}

	private static class RenameKeyProposal extends ChangeCorrectionProposal {

		private final IField fField;

		private final Shell fShell;

		public RenameKeyProposal(String name, int relevance, Image image, IField field, Shell shell) {
			super(name, null, relevance, image);
			fField= field;
			fShell= shell;
		}

		@Override
		public void apply(IDocument document) {
			try {
				RefactoringExecutionStarter.startRenameRefactoring(fField, fShell);
			} catch (CoreException e) {
				JavaPlugin.log(e);
			}
		}

		@Override
		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
			return PropertiesFileEditorMessages.PropertiesCorrectionProcessor_rename_in_workspace_description;
		}

		@Override
		public String getCommandId() {
			return IJavaEditorActionDefinitionIds.RENAME_ELEMENT;
		}
	}

	private PropertiesQuickAssistProcessor() {
	}
}
