/*******************************************************************************
 * 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 org.eclipse.jpt.jpa.core.jpql.JpaJpqlQueryHelper;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.jpa.core.context.NamedQuery;
import org.eclipse.jpt.jpa.ui.JptJpaUiPlugin;
import org.eclipse.jpt.jpa.ui.internal.JptUiIcons;
import org.eclipse.persistence.jpa.jpql.ContentAssistProposals;
import org.eclipse.persistence.jpa.jpql.WordParser;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentifierRole;
import org.eclipse.persistence.jpa.jpql.spi.IEntity;
import org.eclipse.persistence.jpa.jpql.spi.IMapping;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

import static org.eclipse.persistence.jpa.jpql.spi.IMappingType.*;

/**
 * The abstract definition of JPQL content assist support.
 *
 * @version 3.1
 * @since 3.0
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
abstract class JpqlCompletionProposalComputer<T> {

	/**
	 * The current value of the query element.
	 */
	String actualQuery;

	/**
	 * The provider of content assist items based on the position of the cursor within the JPQL query.
	 */
	ContentAssistProposals contentAssistProposals;

	/**
	 * The local registry containing the images used to display the possible proposals. The registry is
	 * disposed when the session ended.
	 */
	private ImageRegistry imageRegistry;

	/**
	 * The same value as {@link #actualQuery} or the modified query that was used by the Hermes parser.
	 */
	String jpqlQuery;

	/**
	 * The JPA model object that is used to access the Java project.
	 */
	NamedQuery namedQuery;

	/**
	 * The start position of the query within the document.
	 */
	int offset;

	/**
	 *
	 */
	private String partialWord;

	/**
	 * The position of the cursor within {@link #actualQuery}.
	 */
	int position;

	/**
	 * This helper is responsible to retrieve the possible proposals to complete or to add more
	 * information to a JPQL based on the position of the cursor.
	 */
	JpaJpqlQueryHelper queryHelper;

	/**
	 * Creates a new <code>JpqlCompletionProposalComputer</code>.
	 */
	public JpqlCompletionProposalComputer() {
		super();
	}

	/**
	 * Adds completion proposals for the abstract schema names that are possible proposals.
	 *
	 * @param proposals The list used to store the new completion proposals
	 */
	private void addAbstractSchemaNames(List<T> proposals) {
		for (IEntity abstractSchemaType : sortByNames(contentAssistProposals.abstractSchemaTypes())) {
			proposals.add(buildAbstractSchemaNameProposal(abstractSchemaType));
		}
	}

	/**
	 * Adds completion proposals for the identification variables that are possible proposals.
	 *
	 * @param proposals The list used to store the new completion proposals
	 */
	private void addIdentificationVariables(List<T> proposals) {
		for (String variable : sort(contentAssistProposals.identificationVariables())) {
			proposals.add(buildIdentificationVariableProposal(variable));
		}
	}

	/**
	 * Adds completion proposals for the JPQL identifiers that are possible proposals.
	 *
	 * @param proposals The list used to store the new completion proposals
	 */
	private void addIdentifiers(List<T> proposals) {
		for (String identifier : sort(contentAssistProposals.identifiers())) {
			proposals.add(buildIdentifierProposal(identifier));
		}
	}

	private String additionalInfo(String proposal) {
		return JpqlIdentifierMessages.localizedMessage(proposal);
	}

	/**
	 * Adds completion proposals for the state fields and association fields that are possible proposals.
	 *
	 * @param proposals The list used to store the new completion proposals
	 */
	private void addMappings(List<T> proposals) {
		for (IMapping mapping : sort(contentAssistProposals.mappings())) {
			proposals.add(buildMappingProposal(mapping));
		}
	}

	private T buildAbstractSchemaNameProposal(IEntity abstractSchemaType) {
		String proposal = abstractSchemaType.getName();
		return buildProposal(proposal, proposal, entityImage());
	}

	private Comparator<IEntity> buildEntityNameComparator() {
		return new Comparator<IEntity>() {
			public int compare(IEntity entity1, IEntity entity2) {
				return entity1.getName().compareTo(entity2.getName());
			}
		};
	}

	private String buildIdentificationVariableDisplayString(String identificationVariable) {

		IEntity abstractSchemaType = contentAssistProposals.getAbstractSchemaType(identificationVariable);

		if (abstractSchemaType != null) {
			StringBuilder sb = new StringBuilder();
			sb.append(identificationVariable);
			sb.append(" : ");
			sb.append(abstractSchemaType.getName());
			identificationVariable = sb.toString();
		}

		return identificationVariable;
	}

	private T buildIdentificationVariableProposal(String proposal) {
		return buildProposal(
			proposal,
			buildIdentificationVariableDisplayString(proposal),
			identificationVariableImage()
		);
	}

	private T buildIdentifierProposal(String proposal) {

		String additionalInfo = additionalInfo(proposal);
		IdentifierRole role = queryHelper.getQueryContext().getExpressionRegistry().getIdentifierRole(proposal);
		boolean realFunction = (role == IdentifierRole.FUNCTION) && isRealFunction(proposal);
		int cursorOffset = 0;

		// There is at least one letter before the cursor, if the setting "Match First Letter Case"
		// is true, then match the case of the JPQL identifier with the first character
		if ((partialWord.length() > 0) && shouldMatchFirstCharacterCase()) {
			if (Character.isLowerCase(partialWord.charAt(0))) {
				proposal = proposal.toLowerCase();
			}
		}
		// Convert the case of the JPQL identifier based on the setting
		else if (shouldUseLowercaseIdentifiers()) {
			proposal = proposal.toLowerCase();
		}

		// For JPQL function, we add () to the display string, example: AVG()
		// But for TRUE, FALSE, etc, we don't add ()
		if (realFunction) {
			proposal += "()";
			cursorOffset--;
		}

		return buildProposal(
			proposal,
			proposal,
			additionalInfo,
			identifierImage(realFunction),
			cursorOffset
		);
	}

	private T buildMappingProposal(IMapping mapping) {
		String proposal = mapping.getName();
		return buildProposal(proposal, proposal, mappingImage(mapping));
	}

	private T buildProposal(String proposal, String displayString, Image image) {
		return buildProposal(proposal, displayString, null, image, 0);
	}

	/**
	 * Creates a new completion proposal for the given proposal.
	 *
	 * @param proposal A valid proposal that can be inserted into the query
	 * @param displayString The human readable string of the proposal
	 * @param additionalInfo Optional additional information about the proposal. The additional
	 * information will be presented to assist the user in deciding if the selected proposal is the
	 * desired choice
	 * @param image The image that represents the proposal
	 * @param cursorOffset An offset that moves the cursor backward or forward after it is adjusted
	 * based on the given proposal
	 * @return The completion proposal
	 */
	abstract T buildProposal(String proposal,
	                         String displayString,
	                         String additionalInfo,
	                         Image image,
	                         int cursorOffset);

	/**
	 * Creates the list of completion proposals based on the current content of the JPQL query and at
	 * the specified position.
	 *
	 * @param namedQuery The model object used to access the application metadata information
	 * @param actualQuery The model object may sometimes be out of sync with the actual content, the
	 * actual query is required for proper content assist
	 * @param offset The beginning of the string within the document
	 * @param position The position of the cursor within the query, which starts at the beginning of
	 * that query and not the document
	 * @return The list of completion proposals
	 */
	final List<T> buildProposals(NamedQuery namedQuery, String actualQuery, int offset, int position) {

		this.offset      = offset;
		this.actualQuery = actualQuery;
		this.namedQuery  = namedQuery;
		this.queryHelper = namedQuery.getJpaProject().getJpaPlatform().getJpqlQueryHelper();

		// It's possible the string has literal representation of the escape characters, if required,
		// convert them into actual escape characters and adjust the position accordingly
		int[] positions  = { position };
		this.jpqlQuery   = modifyJpqlQuery(actualQuery, positions);
		this.position    = positions[0];
		this.partialWord = partialWord();

		List<T> proposals = new ArrayList<T>();

		try {
			this.queryHelper.setQuery(namedQuery, jpqlQuery);
			this.contentAssistProposals = queryHelper.buildContentAssistProposals(positions[0]);

			// Create the proposals for those proposals
			addAbstractSchemaNames    (proposals);
			addIdentificationVariables(proposals);
			addIdentifiers            (proposals);
			addMappings               (proposals);
		}
		finally {
			this.queryHelper.dispose();
		}

		return proposals;
	}

	final void checkCanceled(IProgressMonitor monitor) throws InterruptedException {
		if (monitor.isCanceled()) {
			throw new InterruptedException();
		}
	}

	/**
	 * Clears the information used to retrieve the content assist proposals.
	 */
	final void clearInformation() {

		offset      = -1;
		position    = -1;
		actualQuery = null;
		namedQuery  = null;
		partialWord = null;
		contentAssistProposals = null;
	}

	private Image entityImage() {
		return getImage(JptUiIcons.ENTITY);
	}

	/**
	 * Returns the reason why this computer was unable to produce any completion proposals or
	 * context information.
	 *
	 * @return An error message or <code>null</code> if no error occurred
	 */
	public String getErrorMessage() {
		return null;
	}

	private Image getImage(String key) {
		ImageRegistry imageRegistry = getImageRegistry();
		Image image = imageRegistry.get(key);
		if (image == null) {
			imageRegistry.put(key, getImageDescriptor(key));
			image = imageRegistry.get(key);
		}
		return image;
	}

	private ImageDescriptor getImageDescriptor(String key) {
		return JptJpaUiPlugin.getImageDescriptor(key);
	}

	private ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry(Display.getCurrent());
		}
		return imageRegistry;
	}

	private Image identificationVariableImage() {
		return getImage(JptUiIcons.JPQL_VARIABLE);
	}

	private Image identifierImage(boolean function) {

		if (function) {
			return getImage(JptUiIcons.JPQL_FUNCTION);
		}

		return getImage(JptUiIcons.JPQL_IDENTIFIER);
	}

	private boolean isRealFunction(String identifier) {
		return identifier != Expression.TRUE         &&
		       identifier != Expression.FALSE        &&
		       identifier != Expression.NULL         &&
		       identifier != Expression.CURRENT_DATE &&
		       identifier != Expression.CURRENT_TIME &&
		       identifier != Expression.CURRENT_TIMESTAMP;
	}

	private Image mappingImage(IMapping mapping) {
		switch (mapping.getMappingType()) {
			case BASIC:               return getImage(JptUiIcons.BASIC);
//			case BASIC_COLLECTION:    return getImage(JptUiIcons.ELEMENT_COLLECTION);
//			case BASIC_MAP:           return getImage(JptUiIcons.ELEMENT_COLLECTION);
			case ELEMENT_COLLECTION:  return getImage(JptUiIcons.ELEMENT_COLLECTION);
			case EMBEDDED:            return getImage(JptUiIcons.EMBEDDED);
			case EMBEDDED_ID:         return getImage(JptUiIcons.EMBEDDED_ID);
			case ID:                  return getImage(JptUiIcons.ID);
			case MANY_TO_MANY:        return getImage(JptUiIcons.MANY_TO_MANY);
			case MANY_TO_ONE:         return getImage(JptUiIcons.MANY_TO_ONE);
			case ONE_TO_MANY:         return getImage(JptUiIcons.ONE_TO_MANY);
			case ONE_TO_ONE:          return getImage(JptUiIcons.ONE_TO_ONE);
//			case TRANSFORMATION:      return getImage(JptUiIcons.BASIC);      // TODO
//			case VARIABLE_ONE_TO_ONE: return getImage(JptUiIcons.ONE_TO_ONE); // TODO
			case VERSION:             return getImage(JptUiIcons.VERSION);
			default:                  return getImage(JptUiIcons.TRANSIENT);
		}
	}

	/**
	 * In some context, the given JPQL query needs to be modified before it is parsed.
	 *
	 * @param jpqlQuery The JPQL query to keep unchanged or to modify before parsing it
	 * @param position The position of the cursor within the JPQL query, which needs to be updated if
	 * the query is modified
	 * @return The given JPQL query or a modified version that will be parsed
	 */
	String modifyJpqlQuery(String jpqlQuery, int[] position) {
		return jpqlQuery;
	}

	private String partialWord() {
		WordParser wordParser = new WordParser(jpqlQuery);
		wordParser.setPosition(position);
		return wordParser.partialWord();
	}

	/**
	 * Informs the computer that a content assist session has ended.
	 */
	public void sessionEnded() {

		if (queryHelper != null) {
			queryHelper.disposeProvider();
		}

		clearInformation();

		if (imageRegistry != null) {
			imageRegistry.dispose();
		}
	}

	/**
	 * Informs the computer that a content assist session has started.
	 */
	public void sessionStarted() {
		// Nothing to do
	}

	private boolean shouldMatchFirstCharacterCase() {
		return JptJpaUiPlugin.instance().getPreferenceStore().getBoolean(JptJpaUiPlugin.JPQL_IDENTIFIER_MATCH_FIRST_CHARACTER_CASE_PREF_KEY);
	}

	private boolean shouldUseLowercaseIdentifiers() {
		String value = JptJpaUiPlugin.instance().getPreferenceStore().getString(JptJpaUiPlugin.JPQL_IDENTIFIER_CASE_PREF_KEY);
		return JptJpaUiPlugin.JPQL_IDENTIFIER_LOWERCASE_PREF_VALUE.equals(value);
	}

	private <I extends Comparable<? super I>> Iterable<I> sort(Iterable<I> iterator) {
		return CollectionTools.sort(iterator);
	}

	private Iterable<IEntity> sortByNames(Iterable<IEntity> abstractSchemaTypes) {
		return CollectionTools.sort(abstractSchemaTypes, buildEntityNameComparator());
	}
}