/*=============================================================================#
 # Copyright (c) 2005, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ltk.ui.sourceediting.assist;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.Comparator;

import com.ibm.icu.text.Collator;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension5;
import org.eclipse.jface.text.link.ILinkedModeListener;
import org.eclipse.jface.text.link.InclusivePositionUpdater;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedModeUI;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.jface.text.link.ProposalPosition;
import org.eclipse.jface.text.templates.DocumentTemplateContext;
import org.eclipse.jface.text.templates.GlobalTemplateVariables;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.SearchPattern;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.text.ui.DefaultBrowserInformationInput;
import org.eclipse.statet.ecommons.text.ui.PositionBasedCompletionProposal;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.ITextEditToolSynchronizer;
import org.eclipse.statet.ltk.ui.templates.IWorkbenchTemplateContext;
import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;


/**
 * Like default {@link org.eclipse.jface.text.templates.TemplateProposal}, but
 * <ul>
 *   <li>supports {@link ITextEditToolSynchronizer}</li>
 * </ul>
 */
@NonNullByDefault
public class TemplateProposal extends SourceProposal implements ICompletionProposalExtension5 {
	
	public static class TemplateComparator implements Comparator<TemplateProposal> {
		
		
		private final Collator collator= Collator.getInstance();
		
		
		public TemplateComparator() {
		}
		
		
		@Override
		public int compare(final TemplateProposal arg0, final TemplateProposal arg1) {
			final int result= this.collator.compare(arg0.getTemplate().getName(), arg1.getTemplate().getName());
			if (result != 0) {
				return result;
			}
			return this.collator.compare(arg0.getDisplayString(), arg1.getDisplayString());
		}
		
	}
	
	public static class TemplateProposalParameters<TContext extends AssistInvocationContext>
			extends ProposalParameters<TContext> {
		
		
		public final DocumentTemplateContext templateContext;
		
		public final TextRegion region;
		
		public Template template;
		
		
		@SuppressWarnings("null")
		public TemplateProposalParameters(final DocumentTemplateContext templateContext,
				final TContext context, final TextRegion region,
				final SearchPattern namePattern) {
			super(context, region.getStartOffset(), namePattern);
			
			this.templateContext= templateContext;
			this.region= region;
		}
		
		public TemplateProposalParameters(final Template template,
				final DocumentTemplateContext templateContext,
				/*final TContext context,*/ final TextRegion region) {
			super(null, region.getStartOffset(), null);
			
			this.templateContext= templateContext;
			this.region= region;
			
			this.template= template;
		}
		
	}
	
	
	private final Template template;
	private final DocumentTemplateContext templateContext;
	
	private final Image image;
	
	private TextRegion region;
	
	private @Nullable InclusivePositionUpdater updater;
	
	
	public TemplateProposal(final TemplateProposalParameters<?> parameters,
			final Image image) {
		super(parameters);
		
		this.template= nonNullAssert(parameters.template);
		this.templateContext= nonNullAssert(parameters.templateContext);
		this.image= nonNullAssert(image);
		this.region= nonNullAssert(parameters.region);
	}
	
	public TemplateProposal(final TemplateProposalParameters<?> parameters) {
		this(parameters,
				LTKUIPlugin.getInstance().getImageRegistry().get(LTKUI.OBJ_TEXT_TEMPLATE_IMAGE_ID) );
	}
	
	
	protected TemplateContext getContext() {
		return this.templateContext;
	}
	
	protected Template getTemplate() {
		return this.template;
	}
	
	protected boolean isSelectionTemplate() {
		if (this.templateContext instanceof DocumentTemplateContext) {
			final DocumentTemplateContext docContext= this.templateContext;
			if (docContext.getCompletionLength() > 0) {
				return true;
			}
		}
		return false;
	}
	
	
	@Override
	protected String getName() {
		return this.template.getName();
	}
	
	
	@Override
	public String getSortingString() {
		return this.template.getName();
	}
	
	
	@Override
	public String getDisplayString() {
		return getStyledDisplayString().getString();
	}
	
	@Override
	public StyledString computeStyledText() {
		final StyledString styledText= new StyledString(this.template.getName());
		if (!this.template.getDescription().isEmpty()) {
			styledText.append(QUALIFIER_SEPARATOR, StyledString.QUALIFIER_STYLER);
			styledText.append(this.template.getDescription(), StyledString.QUALIFIER_STYLER);
		}
		return styledText;
	}
	
	@Override
	public Image getImage() {
		return this.image;
	}
	
	
	@Override
	public @Nullable Object getAdditionalProposalInfo(final IProgressMonitor monitor) {
		try {
			final TemplateContext context= getContext();
			context.setReadOnly(true);
			if (context instanceof IWorkbenchTemplateContext) {
				return new DefaultBrowserInformationInput(
						null, getDisplayString(), ((IWorkbenchTemplateContext) context).evaluateInfo(getTemplate()),
						DefaultBrowserInformationInput.FORMAT_SOURCE_INPUT );
			}
			
			final TemplateBuffer templateBuffer= context.evaluate(getTemplate());
			if (templateBuffer != null) {
				return new DefaultBrowserInformationInput(
						null, getDisplayString(), templateBuffer.toString(),
						DefaultBrowserInformationInput.FORMAT_SOURCE_INPUT );
			}
		}
		catch (final TemplateException e) {}
		catch (final BadLocationException e) {}
		return null;
	}
	
	
	@Override
	public boolean isAutoInsertable() {
		if (isSelectionTemplate()) {
			return false;
		}
		return this.template.isAutoInsertable();
	}
	
	
	@Override
	public @Nullable CharSequence getPrefixCompletionText(final IDocument document, final int offset) {
		if (isSelectionTemplate()) {
			return null;
		}
		return super.getPrefixCompletionText(document, offset);
	}
	
	
	@Override
	public void apply(final ITextViewer viewer, final char trigger, final int stateMask, final int offset) {
		final IDocument document= viewer.getDocument();
		final ApplyData applyData= getApplyData();
		
		final Position regionPosition= new Position(this.region.getStartOffset(), this.region.getLength());
		final Position offsetPosition= new Position(offset, 0);
		try {
			document.addPosition(regionPosition);
			document.addPosition(offsetPosition);
			this.templateContext.setReadOnly(false);
			TemplateBuffer templateBuffer;
			try {
				templateBuffer= this.templateContext.evaluate(this.template);
			}
			catch (final TemplateException e1) {
				applyData.setSelection(this.region);
				return;
			}
			
			this.region= LTKSelectionUtils.toTextRegion(regionPosition);
			final int start= getReplaceOffset();
			final int end= Math.max(getReplaceEndOffset(), offsetPosition.getOffset());
			
			// insert template string
			final String templateString= templateBuffer.getString();
			document.replace(start, end - start, templateString);
			
			// translate positions
			final LinkedModeModel model= new LinkedModeModel();
			final TemplateVariable[] variables= templateBuffer.getVariables();
			boolean hasPositions= false;
			for (int i= 0; i != variables.length; i++) {
				final TemplateVariable variable= variables[i];
				
				if (variable.isUnambiguous()) {
					continue;
				}
				
				final LinkedPositionGroup group= new LinkedPositionGroup();
				
				final int[] offsets= variable.getOffsets();
				final int length= variable.getLength();
				
				final String[] values= variable.getValues();
				final ICompletionProposal[] proposals= new ICompletionProposal[values.length];
				for (int j= 0; j < values.length; j++) {
					ensurePositionCategoryInstalled(document, model);
					final Position pos= new Position(offsets[0] + start, length);
					document.addPosition(getCategory(), pos);
					proposals[j]= new PositionBasedCompletionProposal(values[j], pos, length);
				}
				
				for (int j= 0; j < offsets.length; j++) {
					if (j == 0 && proposals.length > 1) {
						group.addPosition(new ProposalPosition(document, offsets[j] + start, length, proposals));
					}
					else {
						group.addPosition(new LinkedPosition(document, offsets[j] + start, length));
					}
				}
				
				model.addGroup(group);
				hasPositions= true;
			}
			
			if (hasPositions) {
				model.forceInstall();
				
				if (this.templateContext instanceof IWorkbenchTemplateContext) {
					final ISourceEditor editor= ((IWorkbenchTemplateContext) this.templateContext).getEditor();
					if (editor.getTextEditToolSynchronizer() != null) {
						editor.getTextEditToolSynchronizer().install(model);
					}
				}
				
				final LinkedModeUI ui= new LinkedModeUI(model, viewer);
				ui.setExitPosition(viewer, getCaretOffset(templateBuffer) + start, 0, Integer.MAX_VALUE);
				ui.enter();
				
				applyData.setSelection(LTKSelectionUtils.toTextRegion(ui.getSelectedRegion()));
			}
			else {
				ensurePositionCategoryRemoved(document);
				applyData.setSelection(getCaretOffset(templateBuffer) + start);
			}
		}
		catch (final BadLocationException | BadPositionCategoryException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, LTKUIPlugin.BUNDLE_ID, 0,
					"Template Evaluation Error",
					e ));
			applyData.clearSelection();
		}
		finally {
			document.removePosition(regionPosition);
			document.removePosition(offsetPosition);
		}
	}
	
	
	private String getCategory() {
		return "TemplateProposalCategory_" + toString(); //$NON-NLS-1$
	}
	
	private void ensurePositionCategoryInstalled(final IDocument document, final LinkedModeModel model) {
		if (!document.containsPositionCategory(getCategory())) {
			document.addPositionCategory(getCategory());
			this.updater= new InclusivePositionUpdater(getCategory());
			document.addPositionUpdater(this.updater);
			
			model.addLinkingListener(new ILinkedModeListener() {
				
				@Override
				public void left(final LinkedModeModel environment, final int flags) {
					ensurePositionCategoryRemoved(document);
				}
				
				@Override
				public void suspend(final LinkedModeModel environment) {}
				@Override
				public void resume(final LinkedModeModel environment, final int flags) {}
			});
		}
	}
	
	private void ensurePositionCategoryRemoved(final IDocument document) {
		if (document.containsPositionCategory(getCategory())) {
			try {
				document.removePositionCategory(getCategory());
			} catch (final BadPositionCategoryException e) {
				// ignore
			}
			document.removePositionUpdater(this.updater);
		}
	}
	
	private int getCaretOffset(final TemplateBuffer buffer) {
		final TemplateVariable[] variables= buffer.getVariables();
		for (int i= 0; i != variables.length; i++) {
			final TemplateVariable variable= variables[i];
			if (variable.getType().equals(GlobalTemplateVariables.Cursor.NAME)) {
				return variable.getOffsets()[0];
			}
		}
		return buffer.getString().length();
	}
	
	/**
	 * Returns the offset of the range in the document that will be replaced by
	 * applying this template.
	 * 
	 * @return the offset of the range in the document that will be replaced by
	 *     applying this template
	 */
	protected final int getReplaceOffset() {
		int start;
		if (this.templateContext instanceof DocumentTemplateContext) {
			final DocumentTemplateContext docContext= this.templateContext;
			start= docContext.getStart();
		}
		else {
			start= this.region.getStartOffset();
		}
		return start;
	}
	
	/**
	 * Returns the end offset of the range in the document that will be replaced
	 * by applying this template.
	 * 
	 * @return the end offset of the range in the document that will be replaced
	 *     by applying this template
	 */
	protected final int getReplaceEndOffset() {
		int end;
		if (this.templateContext instanceof DocumentTemplateContext) {
			final DocumentTemplateContext docContext= this.templateContext;
			end= docContext.getEnd();
		}
		else {
			end= this.region.getEndOffset();
		}
		return end;
	}
	
	@Override
	public int getContextInformationPosition() {
		return this.region.getStartOffset();
	}
	
}
