/*******************************************************************************
 * Copyright (c) 2011, 2012 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.ModifiablePropertyValueModel;
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.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.2
 * @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 ModifiablePropertyValueModel<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,
	                                      ModifiablePropertyValueModel<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);
					validate();
				}
				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 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 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,
	                        ModifiablePropertyValueModel<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.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) {

		namedQuery = (NamedQuery) e.getNewValue();

		if (namedQuery != null) {

			// Prevent undoing the actual query that was set
			sourceViewer.getUndoManager().reset();

			// Make sure the new query is validated
			validate();
		}
		else {
			queryHelper = null;
			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 {
			// The information was disposed but the content might be updated outside of the pane,
			// like in the editor itself, make sure NamedQuery and the helper are initialized
			if (queryHelper == null) {
				namedQuery = query();
				queryHelper = namedQuery.getPersistenceUnit().createJpqlQueryHelper();
			}

			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);
		}
	}
}