/*******************************************************************************
 * 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.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.core.jpql.JpaJpqlQueryHelper;
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.2
 * @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;

	/**
	 * The word before the position of the cursor.
	 */
	private String partialWord;

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

	/**
	 * This helper contains all the information necessary for retrieving the possible proposals
	 * required by content assist and to validate JPQL queries.
	 */
	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) {

		try {
			this.offset      = offset;
			this.actualQuery = actualQuery;
			this.namedQuery  = namedQuery;

			// 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();

			// Create the query helper, initialize it and then retrieve the content assist proposals
			if (this.queryHelper == null) {
				this.queryHelper = namedQuery.getPersistenceUnit().createJpqlQueryHelper();
			}

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

			// Create the proposals for those proposals
			List<T> proposals = new ArrayList<T>();
			addAbstractSchemaNames    (proposals);
			addIdentificationVariables(proposals);
			addIdentifiers            (proposals);
			addMappings               (proposals);

			return proposals;
		}
		finally {
			clearInformation();
		}
	}

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

	/**
	 * Clears the cached information.
	 */
	final void clearInformation() {
		namedQuery  = null;
		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() {

		queryHelper = null;
		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());
	}
}