/*******************************************************************************
 * Copyright (c) 2016 Red Hat Inc. and others.
 * 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:
 *     Mickael Istria (Red Hat Inc.) - [251156] async content assist
 *******************************************************************************/
package org.eclipse.jface.text.contentassist;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.eclipse.osgi.util.NLS;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

import org.eclipse.jface.contentassist.IContentAssistSubjectControl;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextUtilities;

/**
 * This class is used to present proposals asynchronously to the user. If additional information
 * exists for a proposal, then selecting that proposal will result in the information being
 * displayed in a secondary window.
 * 
 * @since 3.12
 */
class AsyncCompletionProposalPopup extends CompletionProposalPopup {

	private static final int MAX_WAIT_IN_MS= 50; // TODO make it a preference
	private List<CompletableFuture<List<ICompletionProposal>>> fFutures;

	private static final class ComputingProposal implements ICompletionProposal, ICompletionProposalExtension {

		private final int fOffset;
		private final int fSize;
		private int fRemaining;
		
		public ComputingProposal(int offset, int size) {
			fSize= size;
			fRemaining = size;
			fOffset = offset;
		}

		@Override
		public void apply(IDocument document) {
			// Nothing to do
		}

		@Override
		public Point getSelection(IDocument document) {
			return new Point(fOffset, 0);
		}

		@Override
		public IContextInformation getContextInformation() {
			return null;
		}

		@Override
		public Image getImage() {
			return null;
		}

		@Override
		public String getDisplayString() {
			return NLS.bind(JFaceTextMessages.getString("AsyncCompletionProposalPopup.computing"), Integer.valueOf(fSize - fRemaining), Integer.valueOf(fSize)); //$NON-NLS-1$
		}

		@Override
		public String getAdditionalProposalInfo() {
			return null;
		}

		@Override
		public void apply(IDocument document, char trigger, int offset) {
			// Nothing to do
		}

		@Override
		public boolean isValidFor(IDocument document, int offset) {
			return false;
		}

		@Override
		public char[] getTriggerCharacters() {
			return null;
		}

		@Override
		public int getContextInformationPosition() {
			return -1;
		}

		public void setRemaining(int size) {
			this.fRemaining = size;
		}
	}

	public AsyncCompletionProposalPopup(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl, AdditionalInfoController infoController) {
		super(contentAssistant, contentAssistSubjectControl, infoController);
	}

	public AsyncCompletionProposalPopup(ContentAssistant contentAssistant, ITextViewer viewer, AdditionalInfoController infoController) {
		super(contentAssistant, viewer, infoController);
	}

	/**
	 * This methods differs from its super as it will show the list of proposals that
	 * gets augmented as the {@link IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)}
	 * complete. All computations operation happen in a non-UI Thread so they're not blocking UI.
	 */
	@Override
	public String showProposals(boolean autoActivated) {
		if (fKeyListener == null)
			fKeyListener= new ProposalSelectionListener();

		final Control control= fContentAssistSubjectControlAdapter.getControl();

		if (!Helper.okToUse(fProposalShell) && control != null && !control.isDisposed()) {
			// add the listener before computing the proposals so we don't move the caret
			// when the user types fast.
			fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);

			fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
			fFilterOffset= fInvocationOffset;
			fLastCompletionOffset= fFilterOffset;
			// start invocation of processors as Futures, and make them populate the proposals upon completion
			List<ICompletionProposal> computedProposals = Collections.synchronizedList(new ArrayList<>());
			fFutures= buildCompletionFuturesOrJobs(fInvocationOffset);
			List<CompletableFuture<Void>> populateFutures = new ArrayList<>(fFutures.size());
			for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
				populateFutures.add(future.thenAccept(proposals ->
					computedProposals.addAll(proposals)
				));
			}

			long requestBeginningTimestamp = System.currentTimeMillis();
			long stillRemainingThreeshold = MAX_WAIT_IN_MS;
			for (CompletableFuture<List<ICompletionProposal>> future : fFutures) {
				try {
					future.get(stillRemainingThreeshold, TimeUnit.MILLISECONDS);
				} catch (TimeoutException | ExecutionException | InterruptedException ex) {
					// future failed or took more time than we want to wait
				}
				stillRemainingThreeshold = MAX_WAIT_IN_MS - (System.currentTimeMillis() - requestBeginningTimestamp);
				if (stillRemainingThreeshold < 0) {
					// we already spent too much time (more than MAX_WAIT_IN_MS), stop waiting.
					break;
				}
			}
			fComputedProposals = computedProposals;
			if (stillRemainingThreeshold > 0) { // everything ready in time, go synchronous
				int count= (computedProposals == null ? 0 : computedProposals.size());
				if (count == 0 && hideWhenNoProposals(autoActivated))
					return null;

				if (count == 1 && !autoActivated && canAutoInsert(computedProposals.get(0))) {
					insertProposal(computedProposals.get(0), (char) 0, 0, fInvocationOffset);
					hide();
				} else {
					createProposalSelector();
					setProposals(computedProposals, false);
					displayProposals();
				}
			} else { // processors took too much time, go asynchronous
				createProposalSelector();
				ComputingProposal computingProposal= new ComputingProposal(fInvocationOffset, fFutures.size());
				computedProposals.add(0, computingProposal);
				fComputedProposals = computedProposals;
				setProposals(fComputedProposals, false);
				Set<CompletableFuture<Void>> remaining = Collections.synchronizedSet(new HashSet<>(populateFutures));
				for (CompletableFuture<Void> populateFuture : populateFutures) {
					populateFuture.thenRun(() -> {
						remaining.removeIf(CompletableFuture::isDone);
						computingProposal.setRemaining(remaining.size());
						if (remaining.isEmpty()) {
							computedProposals.remove(computingProposal);
						}
						List<ICompletionProposal> newProposals = new ArrayList<>(computedProposals);
						fComputedProposals = newProposals;
						Display.getDefault().asyncExec(() -> {
							setProposals(newProposals, false);
							displayProposals();
						});
					});
				}
				displayProposals();
			}
		} else {
			fLastCompletionOffset= fFilterOffset;
			handleRepeatedInvocation();
		}

		return getErrorMessage();
	}
	
	@Override
	public void hide() {
		super.hide();
		if (fFutures != null) {
			for (Future<?> future : fFutures) {
				future.cancel(true);
			}
		}
	}

	protected List<CompletableFuture<List<ICompletionProposal>>> buildCompletionFuturesOrJobs(int invocationOffset) {
		Set<IContentAssistProcessor> processors = null;
		try {
			processors= fContentAssistant.getContentAssistProcessors(getTokenContentType(invocationOffset));
		} catch (BadLocationException e) {
			// ignore
		}
		if (processors == null) {
			return Collections.emptyList();
		}
		List<CompletableFuture<List<ICompletionProposal>>> futures = new ArrayList<>(processors.size());
		for (IContentAssistProcessor processor : processors) {
			futures.add(CompletableFuture.supplyAsync(() ->
				Arrays.asList(processor.computeCompletionProposals(fViewer, invocationOffset))
			));
		}
		return futures;
	}

	private String getTokenContentType(int invocationOffset) throws BadLocationException {
		if (fContentAssistSubjectControl != null) {
			IDocument document= fContentAssistSubjectControl.getDocument();
			if (document != null) {
				return TextUtilities.getContentType(document, fContentAssistant.getDocumentPartitioning(), invocationOffset, true);
			}
		} else {
			return TextUtilities.getContentType(fViewer.getDocument(), fContentAssistant.getDocumentPartitioning(), invocationOffset, true);
		}
		return IDocument.DEFAULT_CONTENT_TYPE;
	}
}
