/*******************************************************************************
 * Copyright (c) 2011 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 *
 ******************************************************************************/
package org.eclipse.jpt.jpa.ui.internal.jpql;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionInfo;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.Trigger;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DefaultTextHover;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.DefaultAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jpt.common.ui.internal.listeners.SWTPropertyChangeListenerWrapper;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.WritablePropertyValueModel;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.NamedQuery;
import org.eclipse.jpt.jpa.ui.internal.JptUiMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.swt.IFocusService;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;

/**
 * This provider installs content assist support on a {@link StyledText} widget in order to give
 * choices at any given position within a JPQL query.
 * <p>
 * TODO. Add syntax highlight for the JPQL identifiers.
 *
 * @version 3.1
 * @since 3.0
 * @author Pascal Filion
 */
@SuppressWarnings({"nls", "restriction"})
public final class JpaJpqlContentProposalProvider extends JpqlCompletionProposalComputer<ICompletionProposal> {

	/**
	 * This model holds onto the {@link Annotation annotations} that have been created for each
	 * {@link JPQLQueryProblem}
	 */
	private AnnotationModel annotationModel;

	/**
	 * The decoration support required to paint the {@link Annotation annotations}, which are the
	 * JPQL problems.
	 */
	private SourceViewerDecorationSupport decorationSupport;

	/**
	 * This handler will trigger an event that will be used to notify the {@link SourceViewer} to
	 * invoke the content assist.
	 */
	private IHandlerActivation handlerActivation;

	/**
	 * The position within the JPQL query.
	 */
	private int position;

	/**
	 * The holder of the named query.
	 */
	private PropertyValueModel<? extends NamedQuery> queryHolder;

	/**
	 * The {@link ResourceBundle} that contains the JPQL problems.
	 */
	private ResourceBundle resourceBundle;

	/**
	 * This viewer is used to install various functionality over the {@link StyledText}.
	 */
	private SourceViewer sourceViewer;

	/**
	 * The configuration object used to configure the {@link SourceViewer}.
	 */
	private JpqlSourceViewerConfiguration sourceViewerConfiguration;

	/**
	 * The widget used to display the JPQL query.
	 */
	private StyledText styledText;

	/**
	 * This listener is used to dispose the {@link org.eclipse.persistence.jpa.jpql.JPQLQueryHelper
	 * JPQLQueryHelper} when the subject changes and to reset the undo manager in order to prevent
	 * the query from being entirely deleted with an undo.
	 */
	private PropertyChangeListener subjectChangeListener;

	/**
	 * The holder of the JPQL query.
	 */
	private WritablePropertyValueModel<String> textHolder;

	/**
	 * Listens to the JPQL query and keep the {@link Document} in sync.
	 */
	private PropertyChangeListener textListener;

	/**
	 * The unique identifier - appended by hashCode() - used to register the widget with the focus
	 * handler.
	 */
	private static final String CONTROL_ID = "jpql.focus.control";

	/**
	 * The unique identifier used to mark an {@link Annotation} as a JPQL problem.
	 */
	private static final String ERROR_TYPE = "org.eclipse.jdt.ui.error";

	/**
	 * Creates a new <code>JpaJpqlContentProposalProvider</code>.
	 *
	 * @param parent The parent {@link Composite} where to add the JPQL query editor
	 * @param queryHolder The holder of the named query
	 * @param textHolder The holder of the JPQL query
	 */
	public JpaJpqlContentProposalProvider(Composite parent,
	                                      PropertyValueModel<? extends NamedQuery> queryHolder,
	                                      WritablePropertyValueModel<String> textHolder) {

		super();
		initialize(parent, queryHolder, textHolder);
	}

	private void activateHandler() {

		IWorkbench workbench = PlatformUI.getWorkbench();
		IFocusService focusService = (IFocusService) workbench.getService(IFocusService.class);
		IHandlerService handlerService = (IHandlerService) workbench.getService(IHandlerService.class);

		if ((focusService != null) && (handlerService != null)) {

			focusService.addFocusTracker(styledText, CONTROL_ID + hashCode());

			Expression expression = buildExpression();
			IHandler handler = buildHandler();

			handlerActivation = handlerService.activateHandler(
				ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS,
				handler,
				expression
			);

			handlerActivation = handlerService.activateHandler(
				ActionFactory.UNDO.getCommandId(),
				handler,
				expression
			);

			handlerActivation = handlerService.activateHandler(
				ActionFactory.REDO.getCommandId(),
				handler,
				expression
			);
		}
	}

	@SuppressWarnings("unchecked")
	private List<AnnotationPreference> annotationPreferences() {
		return EditorsPlugin.getDefault().getMarkerAnnotationPreferences().getAnnotationPreferences();
	}

	private DisposeListener buildDisposeListener() {
		return new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				dispose();
			}
		};
	}

	private IDocumentListener buildDocumentListener() {
		return new IDocumentListener() {
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
			public void documentChanged(DocumentEvent event) {
				try {
					IDocument document = event.getDocument();
					String text = document.get(0, document.getLength());
					textHolder.setValue(text);
				}
				catch (BadLocationException e) {
					// Simply ignore, should never happen
				}
			}
		};
	}

	private Expression buildExpression() {
		return new Expression() {
			@Override
			public void collectExpressionInfo(ExpressionInfo info) {
				info.addVariableNameAccess(ISources.ACTIVE_FOCUS_CONTROL_NAME);
			}
			@Override
			public EvaluationResult evaluate(IEvaluationContext context) {
				Object variable = context.getVariable(ISources.ACTIVE_FOCUS_CONTROL_NAME);
				return (variable == styledText) ? EvaluationResult.TRUE : EvaluationResult.FALSE;
			}
		};
	}

	private FocusListener buildFocusListener() {
		return new FocusListener() {
			public void focusGained(FocusEvent e) {
			}
			public void focusLost(FocusEvent e) {
				// Only dispose the query helper if the content proposal popup doesn't grab the focus
				if (!sourceViewerConfiguration.contentAssistant.hasProposalPopupFocus()) {
					disposeQueryHelper();
				}
			}
		};
	}

	private IHandler buildHandler() {
		return new AbstractHandler() {
			public Object execute(ExecutionEvent event) throws ExecutionException {
				String commandId = event.getCommand().getId();

				// Content Assist
				if (ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS.equals(commandId)) {
					sourceViewer.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
				}
				// Undo
				else if (ActionFactory.UNDO.getCommandId().equals(commandId)) {
					if (sourceViewer.getUndoManager().undoable()) {
						sourceViewer.getUndoManager().undo();
						validate();
					}
				}
				// Redo
				else if (ActionFactory.REDO.getCommandId().equals(commandId)) {
					if (sourceViewer.getUndoManager().redoable()) {
						sourceViewer.getUndoManager().redo();
						validate();
					}
				}

				return null;
			}
		};
	}

	private String buildMessage(JPQLQueryProblem problem) {
		String message = resourceBundle().getString(problem.getMessageKey());
		message = MessageFormat.format(message, (Object[]) problem.getMessageArguments());
		return message;
	}

	private ModifyListener buildModifyListener() {
		return new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				validate();
			}
		};
	}

	private Comparator<JPQLQueryProblem> buildProblemComparator() {
		return new Comparator<JPQLQueryProblem>() {
			public int compare(JPQLQueryProblem problem1, JPQLQueryProblem problem2) {
				int result = problem1.getStartPosition() - problem2.getStartPosition();
				if (result == 0) {
					result = problem1.getEndPosition() - problem2.getEndPosition();
				}
				return result;
			}
		};
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	ICompletionProposal buildProposal(String proposal,
	                                  String displayString,
	                                  String additionalInfo,
	                                  Image image,
	                                  int cursorOffset) {

		return new JpqlCompletionProposal(
			contentAssistProposals,
			proposal,
			displayString,
			additionalInfo,
			image,
			namedQuery,
			actualQuery,
			jpqlQuery,
			offset,
			position,
			cursorOffset,
			false
		);
	}

	private PropertyChangeListener buildSubjectChangeListener() {
		return new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent e) {
				subjectChanged(e);
			}
		};
	}

	private PropertyChangeListener buildTextListener() {
		return new SWTPropertyChangeListenerWrapper(new PropertyChangeListener() {
			public void propertyChanged(PropertyChangeEvent event) {
				String text = (String) event.getNewValue();
				if (text == null) {
					text = StringTools.EMPTY_STRING;
				}
				if (!styledText.getText().equals(text)) {
					sourceViewer.getDocument().set(text);
				}
			}
		});
	}

	private Image contentAssistImage() {
		FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
		return registry.getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage();
	}

	/**
	 * Makes sure the {@link Color} used to paint the underlying problem is disposed when the
	 * {@link StyledText} widget is disposed.
	 */
	private void dispose() {

		sessionEnded();

		decorationSupport.dispose();
		textHolder.removePropertyChangeListener(PropertyValueModel.VALUE, textListener);
		queryHolder.removePropertyChangeListener(PropertyValueModel.VALUE, subjectChangeListener);

		IWorkbench workbench = PlatformUI.getWorkbench();
		IHandlerService handlerService = (IHandlerService) workbench.getService(IHandlerService.class);
		handlerService.deactivateHandler(handlerActivation);
	}

	private void disposeQueryHelper() {
		if (queryHelper != null) {
			queryHelper.dispose();
			queryHelper.disposeProvider();
		}
	}

	private KeyStroke findContentAssistTrigger() {

		IBindingService bindingService = (IBindingService) PlatformUI.getWorkbench().getService(IBindingService.class);

		// Dig through the list of available bindings to find the one for content assist
		for (Binding binding : bindingService.getBindings()) {
			if (isContentAssistBinding(binding)) {
				Trigger[] triggers = binding.getTriggerSequence().getTriggers();
				if ((triggers != null) && (triggers.length > 0)) {
					return (KeyStroke) triggers[0];
				}
			}
		}

		// The default trigger was not found, use the default
		return KeyStroke.getInstance(SWT.CTRL, ' ');
	}

	/**
	 * Returns the widget used to display the JPQL query.
	 *
	 * @return The main widget
	 */
	public StyledText getStyledText() {
		return styledText;
	}

	private void initialize(Composite parent,
	                        PropertyValueModel<? extends NamedQuery> queryHolder,
	                        WritablePropertyValueModel<String> textHolder) {

		this.queryHolder     = queryHolder;
		this.annotationModel = new AnnotationModel();
		this.textHolder      = textHolder;

		// Make sure the StyledText is kept in sync with the text holder
		textListener = buildTextListener();
		textHolder.addPropertyChangeListener(PropertyValueModel.VALUE, textListener);

		// Make sure the user can't delete the entire query when doing undo
		subjectChangeListener = buildSubjectChangeListener();
		queryHolder.addPropertyChangeListener(PropertyValueModel.VALUE, subjectChangeListener);

		// Create the SourceViewer, which is responsible for everything: content assist, tool tip
		// hovering over the annotation (problems), etc
		sourceViewer = new SourceViewer(parent, null, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL | SWT.FLAT);
		sourceViewerConfiguration = new JpqlSourceViewerConfiguration();
		sourceViewer.configure(sourceViewerConfiguration);
		sourceViewer.setDocument(new Document(), annotationModel);
		sourceViewer.getDocument().addDocumentListener(buildDocumentListener());

		styledText = sourceViewer.getTextWidget();
		styledText.addFocusListener(buildFocusListener());
		styledText.addModifyListener(buildModifyListener());
		styledText.addDisposeListener(buildDisposeListener());

		// Add the support for painting the annotations (JPQL problems) in the source viewer
		installDecorationSupport();

		// Bind the content assist key trigger with the handler service
		activateHandler();

		// Install a custom context menu to the widget
		TextTransferHandler.installContextMenu(styledText, sourceViewer.getUndoManager());
	}

	/**
	 * Installs the content assist icon at the top left of the {@link StyledText}.
	 */
	public void installControlDecoration() {

		// Retrieve the content assist trigger
		KeyStroke contentAssistTrigger = findContentAssistTrigger();
		String key = SWTKeySupport.getKeyFormatterForPlatform().format(contentAssistTrigger);

		// Add the context assist icon at the top left corner of the StyledText
		ControlDecoration decoration = new ControlDecoration(styledText, SWT.LEFT | SWT.TOP);
		decoration.setDescriptionText(NLS.bind(JptUiMessages.JpqlContentProposalProvider_Description, key));
		decoration.setImage(contentAssistImage());
		decoration.setShowOnlyOnFocus(true);
	}

	private void installDecorationSupport() {

		decorationSupport = new SourceViewerDecorationSupport(
			sourceViewer,
			null,
			new DefaultMarkerAnnotationAccess(),
			EditorsPlugin.getDefault().getSharedTextColors()
		);

		for (AnnotationPreference preference : annotationPreferences()) {
			decorationSupport.setAnnotationPreference(preference);
		}

		decorationSupport.install(EditorsPlugin.getDefault().getPreferenceStore());
	}

	private boolean isContentAssistBinding(Binding binding) {

		ParameterizedCommand command = binding.getParameterizedCommand();

		return command != null &&
		       command.getCommand() != null &&
		       command.getCommand().getId().equals(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
	}

	private NamedQuery query() {
		return queryHolder.getValue();
	}

	private ResourceBundle resourceBundle() {
		if (resourceBundle == null) {
			resourceBundle = ResourceBundle.getBundle(
				"jpa_jpql_validation",
				Locale.getDefault(),
				JptJpaCorePlugin.class.getClassLoader()
			);
		}
		return resourceBundle;
	}

	private List<JPQLQueryProblem> sortProblems(List<JPQLQueryProblem> problems) {
		Collections.sort(problems, buildProblemComparator());
		return problems;
	}

	private void subjectChanged(PropertyChangeEvent e) {

		disposeQueryHelper();

		// Prevent undoing the actual query that was set
		if (e.getNewValue() != null) {

			namedQuery  = (NamedQuery) e.getNewValue();
			queryHelper = namedQuery.getJpaProject().getJpaPlatform().getJpqlQueryHelper();

			sourceViewer.getUndoManager().reset();
			validate();
		}
		else {
			annotationModel.removeAllAnnotations();
		}
	}

	/**
	 * Validates the given JPQL query and add highlights where problems have been found.
	 */
	private void validate() {

		// First clear any existing problems
		annotationModel.removeAllAnnotations();

		// Nothing to validate
		if ((query() == null) ||
		    styledText.isDisposed() ||
		    StringTools.stringIsEmpty(styledText.getText())) {

			return;
		}

		try {
			String jpqlQuery = styledText.getText();
			queryHelper.setQuery(query(), jpqlQuery);
			String parsedJpqlQuery = queryHelper.getParsedJPQLQuery();

			for (JPQLQueryProblem problem : sortProblems(queryHelper.validate())) {

				// Create the range
				int[] positions = queryHelper.buildPositions(problem, parsedJpqlQuery, jpqlQuery);

				// Add the problem to the tool tip
				Annotation annotation = new Annotation(ERROR_TYPE, true, buildMessage(problem));
				annotationModel.addAnnotation(annotation, new Position(positions[0], positions[1] - positions[0]));
			}
		}
		finally {
			queryHelper.dispose();
		}
	}

	/**
	 * This processor is responsible to create the list of {@link ICompletionProposal proposals}
	 * based on the position of the cursor within the query.
	 */
	private class ContentAssistProcessor implements IContentAssistProcessor {

		/**
		 * {@inheritDoc}
		 */
		public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {

			JpaJpqlContentProposalProvider.this.position = offset;

			String jpqlQuery = viewer.getDocument().get();
			List<ICompletionProposal> proposals = buildProposals(query(), jpqlQuery, 0, position);
			return proposals.toArray(new ICompletionProposal[proposals.size()]);
		}

		/**
		 * {@inheritDoc}
		 */
		public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
			return null;
		}

		/**
		 * {@inheritDoc}
		 */
		public char[] getCompletionProposalAutoActivationCharacters() {
			return null;
		}

		/**
		 * {@inheritDoc}
		 */
		public char[] getContextInformationAutoActivationCharacters() {
			return null;
		}

		/**
		 * {@inheritDoc}
		 */
		public IContextInformationValidator getContextInformationValidator() {
			return null;
		}

		/**
		 * {@inheritDoc}
		 */
		public String getErrorMessage() {
			return null;
		}
	}

	private class JpqlSourceViewerConfiguration extends SourceViewerConfiguration {

		/**
		 * Keeps track of the content assist since we need to know when the popup is opened or not.
		 */
		ContentAssistant contentAssistant;

		private IInformationControlCreator buildInformationControlCreator() {
			return new IInformationControlCreator() {
				public IInformationControl createInformationControl(Shell parent) {
					return new DefaultInformationControl(
						parent,
						EditorsUI.getTooltipAffordanceString(),
						new HTMLTextPresenter(true)
					);
				}
			};
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
			return new DefaultAnnotationHover();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
			contentAssistant = new ContentAssistant();
			contentAssistant.setContentAssistProcessor(new ContentAssistProcessor(), IDocument.DEFAULT_CONTENT_TYPE);
			contentAssistant.setInformationControlCreator(buildInformationControlCreator());
			return contentAssistant;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
			return new DefaultTextHover(sourceViewer);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
			return new DefaultTextHover(sourceViewer);
		}
	}
}