/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Julian Chen - fix for bug #92572, jclRM
 *     Sergey Prigogin (Google) - use parameterized types (bug 442021)
 *******************************************************************************/
package org.eclipse.core.internal.runtime;

import java.util.ArrayList;
import org.eclipse.core.runtime.*;

/**
 * NOT API!!!  This log infrastructure was split from the InternalPlatform.
 * 
 * @since org.eclipse.equinox.common 3.2
 */
public final class RuntimeLog {

	private static ArrayList<ILogListener> logListeners = new ArrayList<>(5);

	/**
	 * Keep the messages until the first log listener is registered.
	 * Once first log listeners is registred, it is going to receive
	 * all status messages accumulated during the period when no log
	 * listener was available.
	 */
	private static ArrayList<IStatus> queuedMessages = new ArrayList<>(5);

	private static PlatformLogWriter logWriter;

	static void setLogWriter(PlatformLogWriter logWriter) {
		synchronized (logListeners) {
			boolean firstListener = isEmpty();
			RuntimeLog.logWriter = logWriter;
			if (firstListener && logWriter != null)
				emptyQueuedMessages();
		}
	}

	/**
	 * See org.eclipse.core.runtime.Platform#addLogListener(ILogListener)
	 */
	public static void addLogListener(ILogListener listener) {
		synchronized (logListeners) {
			boolean firstListener = isEmpty();
			// replace if already exists (Set behaviour but we use an array
			// since we want to retain order)
			logListeners.remove(listener);
			logListeners.add(listener);
			if (firstListener)
				emptyQueuedMessages();
		}
	}

	/**
	 * See org.eclipse.core.runtime.Platform#removeLogListener(ILogListener)
	 */
	public static void removeLogListener(ILogListener listener) {
		synchronized (logListeners) {
			logListeners.remove(listener);
		}
	}

	/**
	 * Checks if the given listener is present
	 */
	public static boolean contains(ILogListener listener) {
		synchronized (logListeners) {
			return logListeners.contains(listener);
		}
	}

	/**
	 * Notifies all listeners of the platform log.
	 */
	public static void log(final IStatus status) {
		// create array to avoid concurrent access
		ILogListener[] listeners = null;
		PlatformLogWriter writer;
		synchronized (logListeners) {
			writer = logWriter;
			if (writer == null) {
				if (logListeners.isEmpty()) {
					queuedMessages.add(status);
					return;
				}
				listeners = logListeners.toArray(new ILogListener[logListeners.size()]);
			}
		}
		if (writer != null) {
			writer.logging(status);
			return;
		}
		if (listeners != null) {
			for (int i = 0; i < listeners.length; i++) {
				try {
					listeners[i].logging(status, IRuntimeConstants.PI_RUNTIME);
				} catch (Exception e) {
					handleException(e);
				} catch (LinkageError e) {
					handleException(e);
				}
			}
		}
	}

	private static void handleException(Throwable e) {
		if (!(e instanceof OperationCanceledException)) {
			// Got a error while logging. Don't try to log again, just put it into stderr 
			e.printStackTrace();
		}
	}

	/**
	 * Helps determine if the logging mechanism is ready for logging.
	 * @return true the logging mechanism is ready for logging.
	 */
	public static boolean isEmpty() {
		synchronized (logListeners) {
			return (logListeners.isEmpty()) && (logWriter == null);
		}
	}

	/**
	 * Determines if there are any listeners
	 * @return true if there is at least one listener.
	 */
	public static boolean hasListeners() {
		synchronized (logListeners) {
			return (!logListeners.isEmpty());
		}
	}

	private static void emptyQueuedMessages() {
		IStatus[] queued;
		synchronized (logListeners) {
			if (queuedMessages.isEmpty())
				return;
			queued = queuedMessages.toArray(new IStatus[queuedMessages.size()]);
			queuedMessages.clear();
		}
		for (int i = 0; i < queued.length; i++) {
			log(queued[i]);
		}
	}

	static void logToListeners(IStatus status) {
		// create array to avoid concurrent access
		ILogListener[] listeners;
		synchronized (logListeners) {
			listeners = logListeners.toArray(new ILogListener[logListeners.size()]);
		}
		for (int i = 0; i < listeners.length; i++) {
			try {
				listeners[i].logging(status, IRuntimeConstants.PI_RUNTIME);
			} catch (Exception e) {
				handleException(e);
			} catch (LinkageError e) {
				handleException(e);
			}
		}
	}

}
