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

import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.jpt.common.core.internal.utility.SimpleTextRange;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.context.AttributeMapping;
import org.eclipse.jpt.jpa.core.context.NamedQuery;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.jpa.core.jpql.spi.IManagedTypeBuilder;
import org.eclipse.jpt.jpa.core.jpql.spi.JpaManagedTypeProvider;
import org.eclipse.jpt.jpa.core.jpql.spi.JpaQuery;
import org.eclipse.jpt.jpa.core.prefs.JpaValidationPreferencesManager;
import org.eclipse.persistence.jpa.jpql.AbstractJPQLQueryHelper;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.spi.IManagedTypeProvider;
import org.eclipse.persistence.jpa.jpql.spi.IMappingBuilder;
import org.eclipse.persistence.jpa.jpql.spi.IQuery;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

/**
 * This helper can perform the following operations over a JPQL query:
 * <ul>
 * <li>Calculates the result type of a query: {@link #getResultType()};</li>
 * <li>Calculates the type of an input parameter: {@link #getParameterType(String)}.</li>
 * <li>Calculates the possible choices to complete the query from a given
 *     position (used for content assist): {@link #buildContentAssistItems(int)}.</li>
 * <li>Validates the query by introspecting its grammar and semantic:
 *     <ul>
 *     <li>{@link #validate()},</li>
 *     <li>{@link #validateGrammar()},</li>
 *     <li>{@link #validateSemantic()}.</li>
 *     </ul></li>
 *
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @version 3.2
 * @since 3.0
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class JpaJpqlQueryHelper extends AbstractJPQLQueryHelper {

	/**
	 * Caches the provider in order to prevent recreating the SPI representation of the JPA artifacts
	 * more than once.
	 */
	private IManagedTypeProvider managedTypeProvider;

	/**
	 * Creates a new <code>JpaQueryHelper</code>.
	 *
	 * @param jpqlGrammar The grammar that defines how to parse a JPQL query
	 */
	protected JpaJpqlQueryHelper(JPQLGrammar jpqlGrammar) {
		super(jpqlGrammar);
	}

	/**
	 * Create the builder that will create the right implementation of {@link org.eclipse.persistence.
	 * jpa.jpql.spi.IManagedType IManagedType}.
	 *
	 * @return A new {@link IMappingBuilder}
	 */
	protected abstract IManagedTypeBuilder buildManagedTypeBuilder();

	/**
	 * Create the builder that will create the right implementation of {@link org.eclipse.persistence.
	 * jpa.jpql.spi.IMapping IMapping}.
	 *
	 * @return A new {@link IMappingBuilder}
	 */
	protected abstract IMappingBuilder<AttributeMapping> buildMappingBuilder();

	/**
	 * Calculates the start and end positions by adjusting them to be at the same position within
	 * <em>jpqlQuery</em>, which may differ from <em>parsedJpqlQuery</em> since the parsed tree does
	 * not keep track of multiple whitespace. The range is also increased if the start and end
	 * positions are the same.
	 *
	 * @param problem The {@link JPQLQueryProblem problem} that was found in the JPQL query, which is
	 * either a grammatical or semantic problem
	 * @param parsedJpqlQuery The string representation of the parsed tree representation of the JPQL
	 * query
	 * @param actualQuery The actual JPQL query that was parsed and validated
	 * @return The start and end positions, which may have been adjusted
	 */
	public int[] buildPositions(JPQLQueryProblem problem, String parsedJpqlQuery, String actualQuery) {

		int startPosition = problem.getStartPosition();
		int endPosition   = problem.getEndPosition();

		// If the start and end positions are the same, then expand the text range
		if (startPosition == endPosition) {
			startPosition = Math.max(startPosition - 1, 0);
		}

		// Reposition the cursor so it's correctly positioned in the actual query, which is the
		// since it may contains more than one whitespace for a single whitespace
		int newStartPosition = ExpressionTools.repositionCursor(parsedJpqlQuery, startPosition, actualQuery);

		if (newStartPosition != startPosition) {
			endPosition  += (newStartPosition - startPosition);
			startPosition = newStartPosition;
		}

		return new int[] { startPosition, endPosition };
	}

	/**
	 * Creates a new {@link IMessage} for the given {@link JPQLQueryProblem}.
	 *
	 * @param namedQuery The model object for which a new {@link IMessage} is creating describing the
	 * problem
	 * @param problem The {@link JPQLQueryProblem problem} that was found in the JPQL query, which is
	 * either a grammatical or semantic problem
	 * @param textRange The range of the JPQL query in the Java source file
	 * @param parsedJpqlQuery The string representation of the parsed tree representation of the JPQL
	 * query, which may differ from the actual JPQL query since it does not keep more than one
	 * whitespace
	 * @param actualQuery The actual JPQL query that was parsed and validated
	 * @param offset This offset is used to move the start position
	 * @return A new {@link IMessage} that has the required information to display the problem
	 * underline and the error message in the Problems view
	 */
	protected IMessage buildProblem(NamedQuery namedQuery,
	                                TextRange textRange,
	                                JPQLQueryProblem problem,
	                                String parsedJpqlQuery,
	                                String actualQuery,
	                                int offset) {

		// Convert the positions from the parsed JPQL query to the actual JPQL query
		int[] positions = buildPositions(problem, parsedJpqlQuery, actualQuery);

		// Now convert the adjusted positions once again to be in the query where the escape
		// characters are in their literal forms
		int[] newStartPosition = { positions[0] };
		ExpressionTools.escape(actualQuery, newStartPosition);
		int escapeOffset = positions[0] - newStartPosition[0];

		positions[0] -= escapeOffset;
		positions[1] -= escapeOffset;

		// Create the text range of the problem
		textRange = new SimpleTextRange(
			textRange.getOffset() + positions[0] + offset,
			positions[1] - positions[0],
			textRange.getLineNumber()
		);

		// Now create the message
		IMessage message = DefaultJpaValidationMessages.buildMessage(
			severity(namedQuery.getResource()),
			problem.getMessageKey(),
			problem.getMessageArguments(),
			namedQuery,
			textRange
		);
		message.setBundleName("jpa_jpql_validation");
		return message;
	}

	/**
	 * Creates a new {@link JpaManagedTypeProvider} which will provide access to the application's
	 * JPA metadata information.
	 *
	 * @param jpaProject The JPA project associated with the Eclipse project
	 * @param persistenceUnit The persistence unit model
	 * @return A new {@link JpaManagedTypeProvider}
	 */
	protected JpaManagedTypeProvider buildProvider(JpaProject jpaProject, PersistenceUnit persistenceUnit) {
		return new JpaManagedTypeProvider(
			jpaProject,
			persistenceUnit,
			buildManagedTypeBuilder(),
			buildMappingBuilder()
		);
	}

	protected String getValidationPreference(NamedQuery namedQuery) {
		return JpaValidationPreferencesManager.getProblemPreference(
				namedQuery.getResource(),
				JpaValidationMessages.JPQL_QUERY_VALIDATION);
	}

	/**
	 * Sets the given named query and string representation of the JPQL query.
	 *
	 * @param namedQuery The model object where the JPQL query is stored
	 * @param actualQuery The actual JPQL query, which can differ from the one owned by the model
	 * object, which happens when the model is out of sync because it has not been updated yet
	 */
	public void setQuery(NamedQuery namedQuery, String actualQuery) {

		if (managedTypeProvider == null) {
			managedTypeProvider = buildProvider(namedQuery.getJpaProject(), namedQuery.getPersistenceUnit());
		}

		IQuery query = new JpaQuery(managedTypeProvider, namedQuery, actualQuery);
		super.setQuery(query);
	}

	/**
	 * Retrieve the severity that is associated to JPQL query validation, which cannot be retrieved
	 * using the JPQL problem message key.

	 * @param targetObject The object for which a new {@link IMessage} is creating describing the
	 * problem
	 * @return The global severity for validating JPQL queries.  The default is {@link IMessage#HIGH_SEVERITY}.
	 */
	protected int severity(IResource targetObject) {
		int severity = JpaValidationPreferencesManager.getProblemSeverityPreference(
				targetObject, JpaValidationMessages.JPQL_QUERY_VALIDATION);
		if (severity == JpaValidationPreferencesManager.NO_SEVERITY_PREFERENCE) {
			return IMessage.HIGH_SEVERITY;
		}
		return severity;
	}
	
	protected boolean shouldValidate(NamedQuery namedQuery) {
		return ! StringTools.stringsAreEqual(
				getValidationPreference(namedQuery), 
				JpaValidationPreferencesManager.IGNORE);
	}

	/**
	 * Validates the given {@link NamedQuery} by validating the JPQL query.
	 *
	 * @param namedQuery The JPQL query to validate
	 * @param jpqlQuery The JPQL query, which might be different from what the model object since
	 * the escape characters should not be in their literal forms (should have '\r' and not '\\r')
	 * @param textRange The range of the JPQL query string within the document
	 * @param offset This offset is used to move the start position
	 * @param messages The list of {@link IMessage IMessages} that will be used to add validation
	 * problems
	 */
	public void validate(NamedQuery namedQuery,
	                     String jpqlQuery,
	                     TextRange textRange,
	                     int offset,
	                     List<IMessage> messages) {

		try {
			// Make this quick check so we don't validate the query, which is time consuming
			if (shouldValidate(namedQuery)) {

				setQuery(namedQuery, jpqlQuery);
				String parsedJpqlQuery = getParsedJPQLQuery();

				for (JPQLQueryProblem problem : validate()) {

					IMessage message = buildProblem(
						namedQuery,
						textRange,
						problem,
						parsedJpqlQuery,
						jpqlQuery,
						offset
					);

					messages.add(message);
				}
			}
		}
		finally {
			// Only dispose the information related to the query
			dispose();
		}
	}
}