/*******************************************************************************
 * Copyright (c) 2017, 2021 Obeo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.acceleo.aql.completion;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.eclipse.acceleo.Error;
import org.eclipse.acceleo.Module;
import org.eclipse.acceleo.ModuleElement;
import org.eclipse.acceleo.aql.completion.proposals.AcceleoCompletionProposal;
import org.eclipse.acceleo.aql.parser.AcceleoAstResult;
import org.eclipse.acceleo.aql.parser.AcceleoParser;
import org.eclipse.acceleo.aql.validation.AcceleoValidator;
import org.eclipse.acceleo.aql.validation.IAcceleoValidationResult;
import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameQueryEnvironment;
import org.eclipse.emf.ecore.EObject;

/**
 * Acceleo service for content assist / auto-completion.
 * 
 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
 */
public class AcceleoCompletor {

	/**
	 * The name space for completion.
	 */
	private static final String TO_COMPLETION_NAMESPACE = "_reserved_::to::completion";

	/**
	 * Provides the {@link List} of {@link AcceleoCompletionProposal completion proposals} available for the
	 * given Acceleo source at the given position in the given environment.
	 * 
	 * @param queryEnvironment
	 *            the {@link IQualifiedNameQueryEnvironment}
	 * @param moduleFileName
	 *            the (non-{@code null}) name of the file containing the module (without extension).
	 * @param source
	 *            the (non-{@code null}) Acceleo text source contents.
	 * @param position
	 *            the caret position in {@code source}.
	 * @return the {@link List} of {@link AcceleoCompletionProposal} for the given source at the given
	 *         position
	 */
	public List<AcceleoCompletionProposal> getProposals(IQualifiedNameQueryEnvironment queryEnvironment,
			String moduleFileName, String source, int position) {
		String moduleQualifiedNameForCompletion = TO_COMPLETION_NAMESPACE + AcceleoParser.QUALIFIER_SEPARATOR
				+ moduleFileName;

		// First, parse the source contents up to the position.
		final AcceleoParser acceleoParser = new AcceleoParser();
		final String partialAcceleoSource = source.substring(0, position);
		final AcceleoAstResult partialAcceleoAstResult = acceleoParser.parse(partialAcceleoSource,
				moduleQualifiedNameForCompletion);

		// Second, validate the AST - this is required further on for the AQL completion.
		final AcceleoAstResult acceleoAstResult = acceleoParser.parse(source,
				moduleQualifiedNameForCompletion);
		queryEnvironment.getLookupEngine().getResolver().register(moduleQualifiedNameForCompletion,
				acceleoAstResult.getModule());
		final List<AcceleoCompletionProposal> proposals;
		try {
			final AcceleoValidator acceleoValidator = new AcceleoValidator(queryEnvironment);
			IAcceleoValidationResult acceleoValidationResult = acceleoValidator.validate(
					partialAcceleoAstResult, moduleQualifiedNameForCompletion);

			// Find which element of the AST we are completing.
			EObject acceleoElementToComplete = getElementToComplete(partialAcceleoAstResult);
			queryEnvironment.getLookupEngine().pushImportsContext(moduleQualifiedNameForCompletion,
					moduleQualifiedNameForCompletion);
			try {
				proposals = this.getProposals(queryEnvironment, partialAcceleoSource, acceleoValidationResult,
						acceleoElementToComplete);
			} finally {
				queryEnvironment.getLookupEngine().popContext(moduleQualifiedNameForCompletion);
			}
		} finally {
			queryEnvironment.getLookupEngine().getResolver().clear(Collections.singleton(
					moduleQualifiedNameForCompletion));
			queryEnvironment.getLookupEngine().clearContext(moduleQualifiedNameForCompletion);
		}

		return proposals;
	}

	/**
	 * Gets the containing {@link ModuleElement} for the given {@link EObject}.
	 * 
	 * @param eObj
	 *            the {@link EObject}
	 * @return the containing {@link ModuleElement} for the given {@link EObject} if any, <code>null</code>
	 *         otherwise
	 */
	private ModuleElement getContainingModuleElement(EObject eObj) {
		ModuleElement res = null;

		EObject current = eObj;
		while (current != null) {
			if (current instanceof ModuleElement) {
				res = (ModuleElement)current;
				break;
			}
			current = current.eContainer();
		}

		return res;
	}

	/**
	 * Provides the {@link List} of {@link AcceleoCompletionProposal completion proposals} for the given
	 * {@link EObject} of an Acceleo AST in the given environment.
	 * 
	 * @param queryEnvironment
	 *            the (non-{@code null}) contextual {@link IQualifiedNameQueryEnvironment}.
	 * @param sourceFragment
	 *            the module source fragment
	 * @param acceleoValidationResult
	 *            the (non-{@code null}) contextual {@link IAcceleoValidationResult}.
	 * @param acceleoElementToComplete
	 *            the {@link EObject Acceleo AST element} to complete.
	 * @return the {@link List} of {@link AcceleoCompletionProposal}.
	 */
	protected List<AcceleoCompletionProposal> getProposals(IQualifiedNameQueryEnvironment queryEnvironment,
			String sourceFragment, IAcceleoValidationResult acceleoValidationResult,
			EObject acceleoElementToComplete) {
		final List<AcceleoCompletionProposal> completionProposals = new ArrayList<>();

		AcceleoAstCompletor acceleoSyntaxCompletor = new AcceleoAstCompletor(queryEnvironment,
				acceleoValidationResult);

		completionProposals.addAll(acceleoSyntaxCompletor.getCompletion(sourceFragment,
				acceleoElementToComplete));

		return completionProposals;
	}

	/**
	 * Provides the Acceleo AST element to complete.
	 * 
	 * @param acceleoAstResult
	 *            the (non-{@code null}) {@link AcceleoAstResult} to complete.
	 * @return the Acceleo AST element to complete.
	 */
	private EObject getElementToComplete(AcceleoAstResult acceleoAstResult) {
		final Error errorToComplete = getErrorToComplete(acceleoAstResult);
		if (errorToComplete == null) {
			final Module moduleToComplete = acceleoAstResult.getModule();
			return moduleToComplete;
		} else {
			return errorToComplete;
		}
	}

	/**
	 * Gets the {@link Error} to use for completion starting point. It's the first error whose
	 * {@link org.eclipse.acceleo.ASTNode#getEndPosition() end} is at the end of the {@link Module}.
	 * 
	 * @param acceleoAstResultToComplete
	 *            the (non-{@code null}) {@link AcceleoAstResult}.
	 * @return the {@link Error} to use as the completion starting point. {@code null} if there is
	 *         {@link AcceleoAstResult#getErrors() no errors} in {@code acceleoAstResultToComplete}.
	 */
	private Error getErrorToComplete(AcceleoAstResult acceleoAstResultToComplete) {
		Objects.requireNonNull(acceleoAstResultToComplete);

		List<Error> errors = acceleoAstResultToComplete.getErrors();
		if (errors.isEmpty()) {
			return null;
		} else {
			Error currentError = errors.get(0);
			int currentErrorEndPosition = acceleoAstResultToComplete.getEndPosition(currentError);

			for (int i = 1; i < errors.size(); i++) {
				final Error candidateError = errors.get(i);
				int candidateErrorEnd = acceleoAstResultToComplete.getEndPosition(candidateError);
				if (candidateErrorEnd > currentErrorEndPosition) {
					currentError = candidateError;
					currentErrorEndPosition = candidateErrorEnd;
				}
			}

			return currentError;
		}
	}

}
