/*******************************************************************************
 * Copyright (c) 2006, 2009 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.statushandlers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.internal.WorkbenchErrorHandlerProxy;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.statushandlers.StatusHandlerRegistry;
import org.eclipse.ui.progress.IProgressConstants;

/**
 * <p>
 * StatusManager is the entry point for all statuses to be reported in the user
 * interface.
 * </p>
 * 
 * <p>
 * Handlers shoudn't be used directly but through the StatusManager singleton
 * which keeps the status handling policy and chooses handlers.
 * <code>StatusManager.getManager().handle(IStatus)</code> and
 * <code>handle(IStatus status, int style)</code> are the methods are the
 * primary access points to the StatusManager.
 * </p>
 * 
 * <p>
 * Acceptable styles (can be combined with logical OR)
 * <ul>
 * <li>NONE - a style indicating that the status should not be acted on. This
 * is used by objects such as log listeners that do not want to report a status
 * twice</li>
 * <li>LOG - a style indicating that the status should be logged only</li>
 * <li>SHOW - a style indicating that handlers should show a problem to an user
 * without blocking the calling method while awaiting user response. This is
 * generally done using a non modal {@link Dialog}</li>
 * <li>BLOCK - a style indicating that the handling should block the calling
 * method until the user has responded. This is generally done using a modal
 * window such as a {@link Dialog}</li>
 * </ul>
 * </p>
 * 
 * <p>
 * Handlers are intended to be accessed via the status manager. The
 * StatusManager chooses which handler should be used for a particular error.
 * There are two ways for adding handlers to the handling flow. First using
 * extension point <code>org.eclipse.ui.statusHandlers</code>, second by the
 * workbench advisor and its method
 * {@link WorkbenchAdvisor#getWorkbenchErrorHandler()}. If a handler is
 * associated with a product, it is used instead of this defined in advisor.
 * </p>
 * 
 * @since 1.0
 * @see AbstractStatusHandler
 */
public class StatusManager {
	/**
	 * A style indicating that the status should not be acted on. This is used
	 * by objects such as log listeners that do not want to report a status
	 * twice.
	 */
	public static final int NONE = 0;

	/**
	 * A style indicating that the status should be logged only.
	 */
	public static final int LOG = 0x01;

	/**
	 * A style indicating that handlers should show a problem to an user without
	 * blocking the calling method while awaiting user response. This is
	 * generally done using a non modal {@link Dialog}.
	 */
	public static final int SHOW = 0x02;

	/**
	 * A style indicating that the handling should block the calling thread
	 * until the status has been handled.
	 * <p>
	 * A typical usage of this would be to ensure that the user's actions are
	 * blocked until they've dealt with the status in some manner. It is
	 * therefore likely but not required that the <code>StatusHandler</code>
	 * would achieve this through the use of a modal dialog. 
	 * </p><p>Due to the fact
	 * that use of <code>BLOCK</code> will block any thread, care should be
	 * taken in this use of this flag.
	 * </p>
	 */
	public static final int BLOCK = 0x04;

	private static StatusManager MANAGER;

	private AbstractStatusHandler statusHandler;

	private List loggedStatuses = new ArrayList();

	private ListenerList listeners = new ListenerList();

	/**
	 * Returns StatusManager singleton instance.
	 * 
	 * @return the manager instance
	 */
	public static StatusManager getManager() {
		if (MANAGER == null) {
			MANAGER = new StatusManager();
		}
		return MANAGER;
	}

	private StatusManager() {
		Platform.addLogListener(new StatusManagerLogListener());
	}

	private AbstractStatusHandler getStatusHandler(){
		if(statusHandler == null && StatusHandlerRegistry.getDefault()
					.getDefaultHandlerDescriptor() != null){
			try {
				statusHandler = StatusHandlerRegistry.getDefault()
						.getDefaultHandlerDescriptor().getStatusHandler();
			} catch (CoreException ex) {
				logError("Errors during the default handler creating", ex); //$NON-NLS-1$
			}
		}
		if(statusHandler == null){
			statusHandler = new WorkbenchErrorHandlerProxy();
		}
		return statusHandler;
	}
	/**
	 * Handles the given status adapter due to the style. Because the facility
	 * depends on Workbench, this method will log the status, if Workbench isn't
	 * initialized and the style isn't {@link #NONE}. If Workbench isn't
	 * initialized and the style is {@link #NONE}, the manager will do nothing.
	 * 
	 * @param statusAdapter
	 *            the status adapter
	 * @param style
	 *            the style. Value can be combined with logical OR. One of
	 *            {@link #NONE}, {@link #LOG}, {@link #SHOW} and
	 *            {@link #BLOCK}.
	 */
	public void handle(StatusAdapter statusAdapter, int style) {
		try {
			// The manager will only log the error when the status adapter or
			// the embedded status is null.
			if (statusAdapter == null) {
				logError(
						"Error occurred during status handling",//$NON-NLS-1$
						new NullPointerException("StatusAdapter object is null")); //$NON-NLS-1$
				return;
			}
			if (statusAdapter.getStatus() == null) {
				logError("Error occurred during status handling",//$NON-NLS-1$
						new NullPointerException("Status object is null")); //$NON-NLS-1$
				return;
			}

			// The manager will only log the status, if Workbench isn't
			// initialized and the style isn't NONE. If Workbench isn't
			// initialized and the style is NONE, the manager will do nothing.
			if (!PlatformUI.isWorkbenchRunning()) {
				if (style != StatusManager.NONE) {
					logError(statusAdapter.getStatus());
				}
				return;
			}

			// delegates the problem to workbench handler
			getStatusHandler().handle(statusAdapter, style);
			
			// if attached status handler is not able to notify StatusManager
			// about particular event, use the default policy and fake the
			// notification
			if (!getStatusHandler().supportsNotification(
					INotificationTypes.HANDLED)) {
				generateFakeNotification(statusAdapter, style);
			}
		} catch (Throwable ex) {
			// The used status handler failed
			logError(statusAdapter.getStatus());
			logError("Error occurred during status handling", ex); //$NON-NLS-1$
		}
	}

	/**
	 * Handles the given status adapter. The {@link #LOG} style is used when
	 * this method is called.
	 * 
	 * @param statusAdapter
	 *            the status adapter
	 */
	public void handle(StatusAdapter statusAdapter) {
		handle(statusAdapter, StatusManager.LOG);
	}

	/**
	 * Handles the given status due to the style. Because the facility depends
	 * on Workbench, this method will log the status, if Workbench isn't
	 * initialized and the style isn't {@link #NONE}. If Workbench isn't
	 * initialized and the style is {@link #NONE}, the manager will do nothing.
	 * 
	 * @param status
	 *            the status to handle
	 * @param style
	 *            the style. Value can be combined with logical OR. One of
	 *            {@link #NONE}, {@link #LOG}, {@link #SHOW} and
	 *            {@link #BLOCK}.
	 */
	public void handle(IStatus status, int style) {
		StatusAdapter statusAdapter = new StatusAdapter(status);
		handle(statusAdapter, style);
	}

	/**
	 * Handles the given status. The {@link #LOG} style is used when this method
	 * is called.
	 * 
	 * @param status
	 *            the status to handle
	 */
	public void handle(IStatus status) {
		handle(status, StatusManager.LOG);
	}

	/**
	 * Handles given CoreException. This method has been introduced to prevent
	 * anti-pattern: <br/><code>
	 * StatusManager.getManager().handle(coreException.getStatus());
	 * </code><br/>
	 * that does not print the stack trace to the log.
	 * 
	 * @param coreException
	 *            a CoreException to be handled.
	 * @param pluginId
	 *            the unique identifier of the relevant plug-in
	 * @see StatusManager#handle(IStatus)
	 * @since 1.1
	 * 
	 */
	public void handle(CoreException coreException,String pluginId) {
		handle(new Status(IStatus.WARNING, pluginId, coreException
				.getLocalizedMessage(), coreException));
	}

	/**
	 * This method informs the StatusManager that this IStatus is being handled
	 * by the handler and to ignore it when it shows up in our ILogListener.
	 * 
	 * @param status
	 *            already handled and logged status
	 */
	public void addLoggedStatus(IStatus status) {
		loggedStatuses.add(status);
	}

	private void logError(String message, Throwable ex) {
		IStatus status = StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH,
				message, ex);
		addLoggedStatus(status);
		WorkbenchPlugin.log(status);
	}

	private void logError(IStatus status) {
		addLoggedStatus(status);
		WorkbenchPlugin.log(status);
	}

	/**
	 * This log listener handles statuses added to a plug-in's log. If our own
	 * WorkbenchErrorHandler inserts it into the log, then ignore it.
	 * 
	 * @see #addLoggedStatus(IStatus)
	 * @since 3.3
	 */
	private class StatusManagerLogListener implements ILogListener {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.runtime.ILogListener#logging(org.eclipse.core.runtime.IStatus,
		 *      java.lang.String)
		 */
		public void logging(IStatus status, String plugin) {
			if (!loggedStatuses.contains(status)) {
				handle(status, StatusManager.NONE);
			} else {
				loggedStatuses.remove(status);
			}
		}
	}

	/**
	 * This method should be called by custom status handlers when an event
	 * occurs. This method has no effect if statushandler does not support
	 * particular event type.
	 * 
	 * @param type
	 *            - type of the event.
	 * @param adapters
	 *            - array of affected {@link StatusAdapter}s.
	 * @see INotificationTypes
	 * @see AbstractStatusHandler#supportsNotification(int)
	 * @since 1.4
	 */
	public void fireNotification(int type, StatusAdapter[] adapters){
		if(getStatusHandler().supportsNotification(type)){
			doFireNotification(type, adapters);
		}
	}
	
	private void doFireNotification(int type, StatusAdapter[] adapters) {
		Object[] oListeners = listeners.getListeners();
		for (int i = 0; i < oListeners.length; i++) {
			if (oListeners[i] instanceof INotificationListener) {
				((INotificationListener) oListeners[i])
						.statusManagerNotified(type, adapters);
			}
		}
	}
	
	private void generateFakeNotification(StatusAdapter statusAdapter, int style) {
		if (((style & StatusManager.SHOW) == StatusManager.SHOW || (style & StatusManager.BLOCK) == StatusManager.BLOCK)
				&& statusAdapter
						.getProperty(IProgressConstants.NO_IMMEDIATE_ERROR_PROMPT_PROPERTY) != Boolean.TRUE) {
			doFireNotification(INotificationTypes.HANDLED,
					new StatusAdapter[] { statusAdapter });
		}
	}
	
	/**
	 * Adds a listener to the StatusManager.
	 * 
	 * @param listener
	 *            - a listener to be added.
	 * @since 1.4
	 */
	public void addListener(INotificationListener listener) {
		this.listeners.add(listener);
	}

	/**
	 * Removes a listener from StatusManager.
	 * 
	 * @param listener
	 *            - a listener to be removed.
	 * @since 1.4
	 */
	public void removeListener(INotificationListener listener){
		this.listeners.remove(listener);
	}
	
	/**
	 * This interface allows for listening to status handling framework changes.
	 * Currently it is possible to be notified when:
	 * <ul>
	 * 	<li>all statuses has been handled</li>.
	 * </ul>
	 * @since 1.4
	 *
	 */
	public interface INotificationListener{
		/**
		 * 
		 * @param type
		 *            - a type of notification.
		 * @param adapters
		 *            - affected {@link StatusAdapter}s
		 */
		public void statusManagerNotified(int type, StatusAdapter[] adapters);
	}
	
	/**
	 * This interface declares types of notification.
	 * 
	 * @since 1.4
	 * @noextend This interface is not intended to be extended by clients.
	 * @noimplement This interface is not intended to be implemented by clients.
	 * 
	 */
	public interface INotificationTypes {

		/**
		 * This type notifications are used when a particular
		 * {@link StatusAdapter} was handled.
		 */
		public static final int HANDLED = 0x01;
		
	}
}
