/****************************************************************************
 * Copyright (c) 2017, 2018 Remain Software
 * 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:
 *    Wim Jongman <wim.jongman@remainsoftware.com> - initial API and implementation
 *****************************************************************************/
package org.eclipse.tips.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.tips.core.internal.FinalTip;

/**
 * Class to provide tips to the tip framework. It is the job of this provider to
 * manage its tips. Examples of managing tips are:
 *
 * <ul>
 * <li>Loading tips from the internet</li>
 * <li>Serve next, previous and current tip on request</li>
 * </ul>
 *
 * After the TipProvider is instantiated by the {@link ITipManager}, the
 * TipManager will insert itself by calling {@link #setManager(ITipManager)}.
 * Then the TipManager will asynchronous call this providers'
 * {@link #loadNewTips(IProgressMonitor)} method. The job of the load() method
 * is to do long work like fetching new tips from the internet and storing them
 * locally. There is no defined method on how tips should be stored locally,
 * implementers are free to do what is needed.
 *
 * The constructor must return fast, meaning that tips may not be fetched from
 * the Internet in the constructor. This should be done in the
 * {@link #loadNewTips(IProgressMonitor)} method.
 *
 * To indicate that this provider is ready to serve tips, it should call the
 * {@link #setTips(List)} method which then sets its <code>ready</code> flag.
 *
 */
public abstract class TipProvider {

	private ITipManager fTipManager;
	private int fTipIndex;
	protected List<Tip> fTips = new ArrayList<>();
	private Tip fCurrentTip;
	private boolean fReady;
	private TipProviderListenerManager fListenerManager = new TipProviderListenerManager();
	private Tip fFinalTip = new FinalTip(getID());
	private String fExpression;

	/**
	 * The zero argument constructor must be able to instantiate the TipProvider.
	 * This method may also be used to quickly set the available tips by calling the
	 * {@link #setTips(List)} method. The constructor may not be used to load tips
	 * from the internet. Use the {@link #loadNewTips(IProgressMonitor)} method for
	 * this purpose.
	 *
	 * @see #loadNewTips(IProgressMonitor)
	 * @see #setTips(List)
	 */
	public TipProvider() {
	}

	/**
	 * Provides the opportunity to release all held resources.
	 */
	public abstract void dispose();

	/**
	 * @return the short description of this provider.
	 */
	public abstract String getDescription();

	/**
	 * @return the ID of this provider
	 */
	public abstract String getID();

	/**
	 * The image used by the UI for low resolution 
	 *
	 * @return a 48x48 {@link TipImage} 
	 */
	public abstract TipImage getImage();

	/**
	 * Get a list of tips. The default implementation returns tips based on the
	 * following conditions: <br>
	 * <dl>
	 * <dt><code>pFilter</code> is false</dt>
	 * <dd>Return all read and unread tips.</dd>
	 * <dt><code>pFilter</code> is true</dt>
	 * <dd>Return read and unread tips if the tipManager may serve unread tips,
	 * otherwise return only unread tips.</dd>
	 * </dl>
	 * <p>
	 * Subclasses may override (calling super(false) to fetch the list) if they want
	 * to serve or sort the list of tips in a different way.
	 *
	 * @param filter
	 *            false or true, see description above.
	 * @return an unmodifiable list of tips.
	 */
	public synchronized List<Tip> getTips(boolean filter) {
		if (filter) {
			return Collections.unmodifiableList(fTips //
					.stream() //
					.filter(tip -> getManager().mustServeReadTips() || !getManager().isRead(tip)) //
					.sorted(Comparator.comparing(Tip::getCreationDate).reversed()) //
					.collect(Collectors.toList()));
		}
		return Collections.unmodifiableList(fTips);
	}

	/**
	 * @return the {@link Tip} that was last returned by {@link #getNextTip()} or
	 *         {@link #getPreviousTip()}
	 */
	public synchronized Tip getCurrentTip() {
		if (fCurrentTip == null) {
			return getNextTip();
		}
		return fCurrentTip;
	}

	/**
	 * The next {@link Tip} is returned based on the read status of the Tip and the
	 * fact if already read tips must be served or not which is known by the
	 * {@link ITipManager}: ({@link ITipManager#mustServeReadTips()}).
	 *
	 * @return the next {@link Tip}
	 * @see #getPreviousTip()
	 * @see #getCurrentTip()
	 */
	public synchronized Tip getNextTip() {
		boolean unreadOnly = !getManager().mustServeReadTips();
		List<Tip> list = getTips(unreadOnly);
		if (list.isEmpty()) {
			return setCurrentTip(fFinalTip);
		}
		if (!unreadOnly && fCurrentTip != null) {
			fTipIndex++;
		} else if (fCurrentTip != null && getManager().isRead(fCurrentTip)) {
			fTipIndex++;
		}
		if (fTipIndex >= list.size()) {
			fTipIndex = 0;
		}
		return setCurrentTip(list.get(fTipIndex));
	}

	/**
	 * @return the previous {@link Tip}
	 * @see #getNextTip()
	 * @see #getCurrentTip()
	 */
	public Tip getPreviousTip() {
		List<Tip> list = getTips(!getManager().mustServeReadTips());
		if (list.isEmpty()) {
			return setCurrentTip(fFinalTip);
		}
		fTipIndex--;
		if (fTipIndex < 0) {
			fTipIndex = list.size() - 1;
		}
		return setCurrentTip(list.get(fTipIndex));
	}

	/**
	 * @return the {@link ITipManager} of this provider, never null.
	 */
	public synchronized ITipManager getManager() {
		return fTipManager;
	}

	/**
	 * @return true if the provider is ready to deliver tips
	 */
	public final boolean isReady() {
		return fReady;
	}

	/**
	 * Is called asynchronously during startup of the TipManager to gather new tips.
	 *
	 * The provider is not available to the UI unless it has called it's
	 * {@link #setTips(List)} method. It is therefore possible that the provider is
	 * not immediately visible in the tip UI but will be added later.
	 * <p>
	 * If you run out of tips and you feel that you should load more tips on your
	 * own then you can also asynchronously call this method. A good place would be
	 * to override {@link #getTips(boolean)}, check if the supply of tips is
	 * sufficient and then call this method asynchronously.
	 * <p>
	 * One strategy is to do a long running fetch in this method and then store the
	 * tips locally. On the next run of the TipManager, the fetched tips can be
	 * served from the constructor (i.e. by calling {@link #setTips(List)}), making
	 * them available immediately
	 *
	 * @param monitor
	 *            The monitor to report back progress.
	 * @return the status in case you want to report problems.
	 * @see TipProvider#setTips(List)
	 * @see TipProvider#isReady()
	 */
	public abstract IStatus loadNewTips(IProgressMonitor monitor);

	private synchronized Tip setCurrentTip(Tip pTip) {
		fCurrentTip = pTip;
		return fCurrentTip;
	}

	/**
	 * Sets the TipManager. You should probably not call this method directly. This
	 * method is normally called after the provider is instantiated by the
	 * {@link ITipManager}. If you create the provider yourself you should register
	 * the provider with {@link ITipManager#register(TipProvider)} which in turn
	 * will call this method. Subclasses may override but must not forget to call
	 * super in order to save the {@link ITipManager}.
	 *
	 * @param tipManager
	 *            the {@link ITipManager}
	 * @return this
	 */
	public synchronized TipProvider setManager(ITipManager tipManager) {
		fTipManager = tipManager;
		return this;
	}

	/**
	 * Sets the tips for this provider, replacing the current set of tips, and sets
	 * the <code>ready</code> flag to true. This method is typically called from the
	 * constructor of the {@link TipProvider} but may also be called from the
	 * asynchronous {@link #loadNewTips(IProgressMonitor)} method.
	 *
	 * @param tips
	 *            a list of {@link Tip} objects
	 * @return this
	 * @see #addTips(List)
	 * @see #isReady()
	 * @see #loadNewTips(IProgressMonitor)
	 */
	public TipProvider setTips(List<Tip> tips) {
		if(getManager().isDisposed()) {
			return this;
		}
		doSetTips(tips, true);
		fReady = true;
		fListenerManager.notifyListeners(TipProviderListener.EVENT_READY, this);
		return this;
	}

	/**
	 * Adds the passed tips to the set of tips this provider already has sets the
	 * <code>ready</code> flag to true. This method is typically called from the
	 * constructor of the {@link TipProvider} but may also be called from the
	 * asynchronous {@link #loadNewTips(IProgressMonitor)} method.
	 *
	 * @param tips
	 *            a list of {@link Tip} objects
	 * @return this
	 * @see #setTips(List)
	 * @see #isReady()
	 * @see #loadNewTips(IProgressMonitor)
	 */
	public TipProvider addTips(List<Tip> tips) {
		doSetTips(tips, false);
		fReady = true;
		fListenerManager.notifyListeners(TipProviderListener.EVENT_READY, this);
		return this;
	}

	private synchronized void doSetTips(List<Tip> tips, boolean replace) {
		if (replace) {
			fTips.clear();
		}
		fTips.addAll(tips);
	}

	/**
	 * Gets the listener manager so that interested parties can subscribe to the
	 * events of this provider.
	 *
	 * @return the {@link TipProviderListenerManager}
	 */
	public TipProviderListenerManager getListenerManager() {
		return fListenerManager;
	}

	/**
	 * Returns an expression that is used by the {@link ITipManager} to determine
	 * the priority of this provider. The expression can be used to advice the
	 * TipManager when the tips of this provider deserve priority. The Eclipse IDE
	 * TipManager uses the core expression from the o.e.core.runtime bundle.
	 * Example: The expression
	 *
	 * <pre>
	 *  &lt;with
	 *     variable="activeWorkbenchWindow.activePerspective"&gt;
	 *         &lt;equals value="org.eclipse.jdt.ui.JavaPerspective"&gt;&lt;/equals&gt;
	 *  &lt;/with&gt;
	 * </pre>
	 *
	 * will give the provider priority when the java perspective is active in the
	 * IDE
	 *
	 * @return the expression which can be empty or null.
	 */
	public String getExpression() {
		return fExpression;
	}

	/**
	 * Sets the expression to determine the priority of the provider.
	 *
	 * @param expression
	 *            the expression, may be null.
	 *
	 * @see #getExpression()
	 */
	public void setExpression(String expression) {
		fExpression = expression;
	}
}