/*/**
 *                                                                            
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 *   
 *  This copyright notice shows up in the generated Java code
 *
 */
package org.eclipse.osbp.xtext.oxtype.ui.contentassist

import com.google.common.base.Function
import com.google.common.base.Predicate
import com.google.inject.Inject
import java.util.List
import org.apache.log4j.Logger
import org.eclipse.core.runtime.Assert
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.jface.text.BadLocationException
import org.eclipse.jface.text.DocumentRewriteSession
import org.eclipse.jface.text.DocumentRewriteSessionType
import org.eclipse.jface.text.IDocument
import org.eclipse.jface.text.IDocumentExtension4
import org.eclipse.jface.text.ITextViewer
import org.eclipse.jface.text.ITextViewerExtension
import org.eclipse.jface.text.contentassist.ICompletionProposal
import org.eclipse.osbp.xtext.oxtype.imports.IShouldImportProvider
import org.eclipse.swt.custom.StyledText
import org.eclipse.text.edits.MultiTextEdit
import org.eclipse.text.edits.ReplaceEdit
import org.eclipse.text.edits.TextEdit
import org.eclipse.xtend.lib.annotations.Data
import org.eclipse.xtext.CrossReference
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.GrammarUtil
import org.eclipse.xtext.ParserRule
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.common.types.JvmDeclaredType
import org.eclipse.xtext.common.types.TypesPackage
import org.eclipse.xtext.conversion.IValueConverter
import org.eclipse.xtext.naming.IQualifiedNameConverter
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.resource.IEObjectDescription
import org.eclipse.xtext.resource.XtextResource
import org.eclipse.xtext.resource.impl.AliasedEObjectDescription
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal.IReplacementTextApplier
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
import org.eclipse.xtext.ui.editor.contentassist.ReplacementTextApplier
import org.eclipse.xtext.util.ReplaceRegion
import org.eclipse.xtext.xbase.XbasePackage
import org.eclipse.xtext.xbase.conversion.XbaseQualifiedNameValueConverter
import org.eclipse.xtext.xbase.imports.RewritableImportSection
import org.eclipse.xtext.xbase.ui.contentassist.XbaseReferenceProposalCreator
import org.eclipse.xtext.xbase.ui.imports.ReplaceConverter
import org.eclipse.xtext.xtype.XImportSection

import static org.eclipse.xtext.util.Strings.notNull
import org.eclipse.osbp.xtext.oxtype.imports.OXTypeRewritableImportSection

@SuppressWarnings("restriction")
class OXtypeProposalProvider extends AbstractOXtypeProposalProvider {

	@Inject IShouldImportProvider importProvider

	override void lookupCrossReference(CrossReference crossReference, EReference reference,
		ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor,
		Predicate<IEObjectDescription> filter) {
			var String ruleName = null;
			if (crossReference.getTerminal() instanceof RuleCall) {
				ruleName = (crossReference.getTerminal() as RuleCall).getRule().getName();
			}

			if (importProvider.shouldAutoImport(contentAssistContext.getCurrentModel(), reference)) {
				// if the type should be imported, pass a custom acceptor to pass additional information to the wrapped proposal factory
				val customAcceptor = new ImportAwareCompletionProposalAcceptor(acceptor, contentAssistContext);
				lookupCrossReference(contentAssistContext.getCurrentModel(), reference, customAcceptor, filter,
					getProposalFactory(ruleName, contentAssistContext));
			} else {
				lookupCrossReference(contentAssistContext.getCurrentModel(), reference, acceptor, filter,
					getProposalFactory(ruleName, contentAssistContext));
			}
		}

		override void lookupCrossReference(CrossReference crossReference, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor, Predicate<IEObjectDescription> filter,
			Function<IEObjectDescription, ICompletionProposal> proposalFactory) {
			val ParserRule containingParserRule = GrammarUtil.containingParserRule(crossReference);
			if (!GrammarUtil.isDatatypeRule(containingParserRule)) {
				val EReference ref = GrammarUtil.getReference(crossReference);
				if (importProvider.shouldAutoImport(contentAssistContext.getCurrentModel(), ref)) {
					// if the type should be imported, pass a custom acceptor to pass additional information to the wrapped proposal factory
					val customAcceptor = new ImportAwareCompletionProposalAcceptor(acceptor, contentAssistContext);
					lookupCrossReference(contentAssistContext.getCurrentModel(), ref, customAcceptor, filter,
						proposalFactory);
				} else {
					lookupCrossReference(contentAssistContext.getCurrentModel(), ref, acceptor, filter,
						proposalFactory);
				}
			}
		}

		/**
		 * Is responsible to create the completion proposals
		 */
		static class CustomReferenceProposalCreator extends XbaseReferenceProposalCreator {

			@Inject IShouldImportProvider importProvider
			@Inject IQualifiedNameConverter nameConverter

			@Inject
			private RewritableImportSection.Factory importSectionFactory;

			@Inject
			private ReplaceConverter replaceConverter;

			@Inject
			XbaseQualifiedNameValueConverter valueConverter;

			override void lookupCrossReference(IScope scope, EObject model, EReference reference,
				ICompletionProposalAcceptor acceptor, Predicate<IEObjectDescription> filter,
				Function<IEObjectDescription, ICompletionProposal> proposalFactory) {
				if (TypesPackage.Literals.JVM_TYPE.isSuperTypeOf(getEReferenceType(model, reference)) ||
					reference === XbasePackage.Literals.XABSTRACT_FEATURE_CALL__FEATURE) {
					super.lookupCrossReference(scope, model, reference, acceptor, filter, proposalFactory)
					return
				}

				val Function<IEObjectDescription, ICompletionProposal> wrappedFactory = getWrappedFactory(scope, model,
					reference, proposalFactory, acceptor);
				if (importProvider.shouldProposeAllElements(model, reference)) {
					for (IEObjectDescription candidate : scope.allElements) {
						if (!acceptor.canAcceptMoreProposals())
							return;

						var transformed = candidate
						val name = candidate.name;
						if (name.segmentCount > 1) {
							transformed = new AliasedEObjectDescription(QualifiedName.create(name.lastSegment),
								candidate)
						}

						if (filter.apply(transformed)) {
							acceptor.accept(wrappedFactory.apply(transformed));
						}
					}
				} else {
					val Iterable<IEObjectDescription> candidates = queryScope(scope, model, reference, filter);
					for (IEObjectDescription candidate : candidates) {
						if (!acceptor.canAcceptMoreProposals())
							return;
						if (filter.apply(candidate)) {
							acceptor.accept(wrappedFactory.apply(candidate));
						}
					}
				}

			}

			def Function<IEObjectDescription, ICompletionProposal> getWrappedFactory(IScope scope, EObject model,
				EReference reference, Function<IEObjectDescription, ICompletionProposal> proposalFactory,
				ICompletionProposalAcceptor acceptor) {
				if (!TypesPackage.Literals.JVM_TYPE.isSuperTypeOf(getEReferenceType(model, reference)) &&
					acceptor instanceof ImportAwareCompletionProposalAcceptor) {

					// create the default factory
					val factory = super.getWrappedFactory(model, reference, proposalFactory)

					// wrap the factory and initialize the text applier for import stuff
					val customAcceptor = acceptor as ImportAwareCompletionProposalAcceptor
					val complContext = customAcceptor.context
					return new Function<IEObjectDescription, ICompletionProposal>() {
						override ICompletionProposal apply(IEObjectDescription from) {
							val ICompletionProposal result = factory.apply(from);
							if (result instanceof ConfigurableCompletionProposal) {
								result.textApplier = createTextApplier(complContext, scope, nameConverter,
									valueConverter)
								result.setAdditionalData(IEObjectDescription.name, from)
							}
							return result;
						}
					};
				} else {
					return super.getWrappedFactory(model, reference, proposalFactory);
				}
			}

			def IReplacementTextApplier createTextApplier(ContentAssistContext context, IScope typeScope,
				IQualifiedNameConverter qualifiedNameConverter, IValueConverter<String> valueConverter) {
				if (EcoreUtil2.getContainerOfType(context.getCurrentModel(), XImportSection) !== null)
					return null;
				return new FQNImporter(context.getResource(), context.getViewer(), typeScope, qualifiedNameConverter,
					valueConverter, importSectionFactory, replaceConverter);
			}
		}

		static class FQNImporter extends ReplacementTextApplier {

			private static final Logger LOG = Logger.getLogger(FQNImporter);
			private final ITextViewer viewer;

			RewritableImportSection.Factory importSectionFactory;

			ReplaceConverter replaceConverter;

			IValueConverter<String> valueConverter

			IQualifiedNameConverter qualifiedNameConverter

			IScope scope

			Resource context

			new(Resource context, ITextViewer viewer, IScope scope, IQualifiedNameConverter qualifiedNameConverter,
				IValueConverter<String> valueConverter, RewritableImportSection.Factory importSectionFactory,
				ReplaceConverter replaceConverter) {
				this.viewer = viewer;
				this.context = context
				this.qualifiedNameConverter = qualifiedNameConverter;
				this.scope = scope;
				this.qualifiedNameConverter = qualifiedNameConverter;
				this.valueConverter = valueConverter
				this.importSectionFactory = importSectionFactory;
				this.replaceConverter = replaceConverter;
			}

			override void apply(IDocument document,
				ConfigurableCompletionProposal proposal) throws BadLocationException {

				val IEObjectDescription desc = proposal.getAdditionalData(IEObjectDescription.name) as IEObjectDescription

				val toImportQualifiedName = desc.qualifiedName
				val String proposalReplacementString = proposal.getReplacementString();
				var String typeName = proposalReplacementString;
				if (valueConverter !== null)
					typeName = valueConverter.toValue(toImportQualifiedName.toString, null);
				val String replacementString = getActualReplacementString(proposal);
				// there is an import statement - apply computed replacementString
				if (!proposalReplacementString.equals(replacementString)) {
					var String shortTypeName = replacementString;
					if (valueConverter !== null)
						shortTypeName = valueConverter.toValue(replacementString, null);
					val QualifiedName shortQualifiedName = qualifiedNameConverter.toQualifiedName(shortTypeName);
					if (shortQualifiedName.getSegmentCount() === 1) {
						proposal.setCursorPosition(replacementString.length());
						document.replace(proposal.getReplacementOffset(), proposal.getReplacementLength(),
							replacementString);
						return;
					}
				}

				// we could create an import statement if there is no conflict
				val QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(typeName);
				if (qualifiedName.getSegmentCount() === 1) {
					// type resides in default package - no need to hassle with imports
					proposal.setCursorPosition(proposalReplacementString.length());
					document.replace(proposal.getReplacementOffset(), proposal.getReplacementLength(),
						proposalReplacementString);
					return;
				}
				val IEObjectDescription description = scope.getSingleElement(
					qualifiedName.skipFirst(qualifiedName.getSegmentCount() - 1));
				if (description !== null) {
					// already imported
					proposal.setCursorPosition(proposalReplacementString.length());
					document.replace(proposal.getReplacementOffset(), proposal.getReplacementLength(),
						proposalReplacementString);
					return;
				}

				// Import does not introduce ambiguities - add import and insert short name
				val String shortName = qualifiedName.getLastSegment();
				var int topPixel = -1;
				// store the pixel coordinates to prevent the ui from flickering
				val StyledText widget = viewer.getTextWidget();
				if (widget !== null)
					topPixel = widget.getTopPixel();
				var ITextViewerExtension viewerExtension = null;
				if (viewer instanceof ITextViewerExtension) {
					viewerExtension = viewer as ITextViewerExtension;
					viewerExtension.setRedraw(false);
				}

				val OXTypeRewritableImportSection importSection = importSectionFactory.parse(context as XtextResource) as OXTypeRewritableImportSection;
				val IEObjectDescription typeToImport = scope.getSingleElement(qualifiedName);
				if (typeToImport === null) {
					LOG.error("Could not find unique type named '" + notNull(qualifiedName) + "' in scope");
					if (viewerExtension !== null)
						viewerExtension.setRedraw(true);
					return;
				}
				val EObject resolved = EcoreUtil.resolve(typeToImport.getEObjectOrProxy(), context);
				Assert.isTrue(!resolved.eIsProxy());
				importSection.addFQNImport(typeName);

				var DocumentRewriteSession rewriteSession = null;
				try {
					if (document instanceof IDocumentExtension4) {
						rewriteSession = (document as IDocumentExtension4).startRewriteSession(
							DocumentRewriteSessionType.UNRESTRICTED_SMALL);
					}
					// apply short proposal
					var String escapedShortname = shortName;
					if (valueConverter !== null) {
						escapedShortname = valueConverter.toString(shortName);
					}
					proposal.setCursorPosition(escapedShortname.length());
					val int initialCursorLine = document.getLineOfOffset(proposal.getReplacementOffset());
					val ReplaceEdit replaceEdit = new ReplaceEdit(proposal.getReplacementOffset(),
						proposal.getReplacementLength(), escapedShortname);

					// add import statement
					val List<ReplaceRegion> importChanges = importSection.rewrite();
					var TextEdit textEdit = replaceConverter.convertToTextEdit(importChanges);
					if (textEdit !== null) {
						val MultiTextEdit compound = new MultiTextEdit();
						compound.addChild(textEdit);
						compound.addChild(replaceEdit);
						textEdit = compound;
					} else {
						textEdit = replaceEdit;
					}
					textEdit.apply(document);

					val int cursorPosition = proposal.getCursorPosition() +
						replaceConverter.getReplaceLengthDelta(importChanges, proposal.getReplacementOffset());
					proposal.setCursorPosition(cursorPosition);
					val int newCursorLine = document.getLineOfOffset(cursorPosition);

					// set the pixel coordinates
					if (widget !== null) {
						val int additionalTopPixel = (newCursorLine - initialCursorLine) * widget.getLineHeight();
						widget.setTopPixel(topPixel + additionalTopPixel);
					}
				} finally {
					if (rewriteSession !== null) {
						(document as IDocumentExtension4).stopRewriteSession(rewriteSession);
					}
					if (viewerExtension !== null)
						viewerExtension.setRedraw(true);
				}
			}

			override getActualReplacementString(ConfigurableCompletionProposal proposal) {

				var String replacementString = proposal.getReplacementString();
				if (scope !== null) {
					var String qualifiedNameAsString = replacementString;
					if (valueConverter !== null) {
						qualifiedNameAsString = valueConverter.toValue(qualifiedNameAsString, null);
					}
					val IEObjectDescription element = scope.getSingleElement(
						qualifiedNameConverter.toQualifiedName(qualifiedNameAsString));
					if (element !== null) {
						val EObject resolved = EcoreUtil.resolve(element.getEObjectOrProxy(), context);
						if (!resolved.eIsProxy()) {
							val IEObjectDescription shortendElement = scope.getSingleElement(resolved);
							if (shortendElement !== null)
								replacementString = applyValueConverter(shortendElement.getName());
						}
					}
				}
				return replacementString;

			}

			def protected String applyValueConverter(QualifiedName qualifiedName) {
				var String result = qualifiedNameConverter.toString(qualifiedName);
				if(valueConverter !== null) result = valueConverter.toString(result);
				return result;
			}
		}

		@Data
		static class ImportAwareCompletionProposalAcceptor extends ICompletionProposalAcceptor.Delegate {
			final ContentAssistContext context

			new(ICompletionProposalAcceptor delegate, ContentAssistContext context) {
				super(delegate)
				this.context = context
			}

		}
	}
	