/*******************************************************************************
 * Copyright (c) 2005 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
 *******************************************************************************/
/*
 *  $RCSfile: AbstractWorkBenchRenderer.java,v $
 *  $Revision: 1.3 $  $Date: 2005/05/18 21:58:34 $ 
 */
package org.eclipse.jem.util.logger.proxyrender;

import java.util.logging.Level;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.adaptor.EclipseStarter;
import org.osgi.framework.Bundle;

import org.eclipse.jem.util.logger.proxy.*;


/**
 * Base log renderer that logs to the workbench.
 * 
 * @since 1.1.0
 */
public abstract class AbstractWorkBenchRenderer implements ILogRenderer2 {

	private boolean fTraceMode = false; // will we actually punch trace messaged or not

	private boolean fSettingTrace = false;

	protected Bundle fMyBundle = null;

	protected Logger fMyLogger = null;

	protected ILog fWorkBenchLogger = null;

	/**
	 * Constructer taking a logger.
	 * 
	 * @param logger
	 * 
	 * @since 1.1.0
	 */
	public AbstractWorkBenchRenderer(Logger logger) {
		super();
		fMyLogger = logger;
		fTraceMode = fMyLogger.getTraceMode();

		String pluginID = fMyLogger.getPluginID();
		fMyBundle = Platform.getBundle(pluginID);
		if (fMyBundle == null)
			throw new RuntimeException("Invalid Plugin ID"); //$NON-NLS-1$

		fWorkBenchLogger = Platform.getLog(fMyBundle);
		setTraceMode(fMyLogger.getTraceMode() || isDebugging(fMyBundle));
		fMyLogger.setRenderer(this);
	}

	/*
	 * This used to come from the Plugin instance. But in new OSGi, there is not necessarily a Plugin instance. So use the same logic they use.
	 */
	private boolean isDebugging(Bundle bundle) {
		String symbolicName = bundle.getSymbolicName();
		if (symbolicName != null) {
			String key = symbolicName + "/debug"; //$NON-NLS-1$
			String value = Platform.getDebugOption(key);
			return value == null ? false : value.equalsIgnoreCase("true"); //$NON-NLS-1$
		}
		return false;
	}

	/**
	 * Is the console log for eclipse turned on to sysout. If true, then we shouldn't log to console anything already logged because Eclipse would of
	 * logged it for us. This comes from the -Declipse.consoleLog="true" which is the default when starting eclipse from PDE.
	 */
	protected static final boolean consoleLogOn = "true".equals(System.getProperty(EclipseStarter.PROP_CONSOLE_LOG)); //$NON-NLS-1$

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer#setTraceMode(boolean)
	 */
	public void setTraceMode(boolean flag) {
		if (fSettingTrace)
			return; // Do not allow cycles

		fSettingTrace = true;
		fTraceMode = flag;
		fMyLogger.setTraceMode(flag);
		fSettingTrace = false;
	}

	// The following methods are for historical renderers in case this has been subclassed outside
	// of util.

	/**
	 * Log a string to the trace.
	 * 
	 * @param param
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public abstract String log(String param);

	/**
	 * Default one that log a string to the trace given a level. Default simply passes it to log(String) so that we don't break old subclasses.
	 * <p>
	 * If loggedToWorkbench is true, then it shouldn't be logged to console if consoleLogOn is true because workbench already logged to console.
	 * 
	 * @param msg
	 * @param l
	 * 
	 * @since 1.0.0
	 */
	protected void log(String msg, Level l, boolean loggedToWorkbench) {
		log(msg);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer#log(java.lang.String, int)
	 */
	public String log(String msg, int type) {

		String target = logWorkBench(msg, type);
		if (fTraceMode || target.equals(NOLOG_DESCRIPTION))
			return log(msg);
		else
			return target;
	}

	/**
	 * Log to workbench, a string of the given level <code>ILogRenderer.LOG_</code>. levels.
	 * 
	 * @param msg
	 * @param type
	 * @return description of the log's destination e.g., <code>CONSOLE_DESCRIPTION</code>
	 * 
	 * @see ILogRenderer#LOG_ERROR and all of the other log types.
	 * @see ILogRenderer#CONSOLE_DESCRIPTION
	 * @since 1.0.0
	 */
	public String logWorkBench(String msg, int type) {

		try {
			int ErrCode;
			if (fWorkBenchLogger != null) {
				switch (type) {
					case (ILogRenderer.LOG_ERROR):
						ErrCode = IStatus.ERROR;
						break;
					case (ILogRenderer.LOG_WARNING):
						ErrCode = IStatus.WARNING;
						break;
					case (ILogRenderer.LOG_INFO):
						ErrCode = IStatus.INFO;
						break;
					case (ILogRenderer.LOG_TRACE):
						ErrCode = IStatus.OK;
						break;
					default:
						throw new RuntimeException("Invalid Log Type"); //$NON-NLS-1$
				}
				Status status = new Status(ErrCode, fMyBundle.getSymbolicName(), IStatus.OK, msg, null);
				fWorkBenchLogger.log(status);
				return WORKBENCH_DESCRIPTION;
			} else
				return NOLOG_DESCRIPTION;
		} catch (Throwable t) {
			return NOLOG_DESCRIPTION;
		}
	}

	// Default implentation of the ILogRenderer2 interface.
	protected boolean isLogging(Level level) {
		return fTraceMode || fMyLogger.isLoggingLevel(level);
	}

	private static final int[] STATUS_LEVEL;

	private static final Level[] STATUS_LEVEL_LOOKUP;

	private static final Level[] LEVEL_STATUS;

	static {
		// Status levels that correspond to the log levels, from finest to none, same indexes as from STATUS_LEVEL_LOOKUP.
		STATUS_LEVEL_LOOKUP = new Level[] { Level.INFO, Level.WARNING, Level.SEVERE};
		STATUS_LEVEL = new int[] { IStatus.INFO, IStatus.WARNING, IStatus.ERROR};

		// Levels that correspond to the IStatus levels.
		int maxID = Math.max(IStatus.OK, Math.max(IStatus.INFO, Math.max(IStatus.WARNING, IStatus.ERROR)));
		LEVEL_STATUS = new Level[maxID + 1];
		LEVEL_STATUS[IStatus.OK] = Level.FINE;
		LEVEL_STATUS[IStatus.INFO] = Level.INFO;
		LEVEL_STATUS[IStatus.WARNING] = Level.WARNING;
		LEVEL_STATUS[IStatus.ERROR] = Level.SEVERE;
	}

	/**
	 * Return the Java Level for the status code from the given IStatus.
	 * 
	 * @param status
	 * @return the Java Level
	 * 
	 * @since 1.0.0
	 */
	protected Level getLogLevel(IStatus status) {
		return LEVEL_STATUS[status.getSeverity()];
	}

	/**
	 * Return the IStatus status code for the given Java Level.
	 * 
	 * @param logLevel
	 * @return the IStatus status code.
	 * 
	 * @since 1.0.0
	 */
	protected int getStatusSeverity(Level logLevel) {
		for (int i = 0; i < STATUS_LEVEL_LOOKUP.length; i++) {
			if (STATUS_LEVEL_LOOKUP[i] == logLevel)
				return STATUS_LEVEL[i];
		}
		return IStatus.OK; // Default to ok.
	}

	/**
	 * Log the string to the workbench for the given level
	 * 
	 * @param msg
	 * @param level
	 * @return description of the log's destination e.g., <code>CONSOLE_DESCRIPTION</code>
	 * 
	 * @since 1.1.0
	 */
	protected String logWorkbench(String msg, Level level) {
		String result = NOLOG_DESCRIPTION;
		// Test again because we could be here simply due to trace mode, in which case we
		// don't want to workbench log it.
		if (fMyLogger.isLoggingLevel(level)) {
			Platform.getLog(fMyBundle).log(new Status(getStatusSeverity(level), fMyBundle.getSymbolicName(), 0, msg, null));
			result = WORKBENCH_DESCRIPTION;
			if (fTraceMode)
				log(msg, level, true);
		} else if (fTraceMode)
			log(msg, level, false);
		return result;
	}

	private String getStatusMsg(IStatus s, Level l) {
		if (s.getException() != null)
			return fMyLogger.getGenericMsg(s.toString() + fMyLogger.fLineSeperator + fMyLogger.exceptionToString(s.getException()), l);
		else
			return fMyLogger.getGenericMsg(s.toString(), l);
	}

	/**
	 * Log the IStatus to the workbench at the given level.
	 * 
	 * @param s
	 * @param level
	 * @return description of the log's destination e.g., <code>CONSOLE_DESCRIPTION</code>
	 * 
	 * @since 1.0.0
	 */
	protected String logWorkbench(IStatus s, Level level) {
		if (level == DEFAULT)
			level = getLogLevel(s);
		String result = NOLOG_DESCRIPTION;
		// Test again because we could be here simply due to trace mode, in which case we
		// don't want to workbench log it.
		if (fMyLogger.isLoggingLevel(level)) {
			Platform.getLog(fMyBundle).log(s);
			result = WORKBENCH_DESCRIPTION;
			if (fTraceMode)
				log(getStatusMsg(s, level), level, true);
		} else if (fTraceMode)
			log(getStatusMsg(s, level), level, false);
		return result;
	}

	/**
	 * Log to the workbench the Throwable at the given level.
	 * 
	 * @param t
	 * @param level
	 * @return description of the log's destination e.g., <code>CONSOLE_DESCRIPTION</code>
	 * 
	 * @since 1.0.0
	 */
	protected String logWorkbench(Throwable t, Level level) {
		String result = NOLOG_DESCRIPTION;
		// Test again because we could be here simply due to trace mode, in which case we
		// don't want to workbench log it.
		if (fMyLogger.isLoggingLevel(level)) {
			Platform.getLog(fMyBundle).log(new Status(getStatusSeverity(level), fMyBundle.getSymbolicName(), 0, "Exception thrown.", t)); //$NON-NLS-1$
			result = WORKBENCH_DESCRIPTION;
			if (fTraceMode)
				log(fMyLogger.getGenericMsg(fMyLogger.exceptionToString(t), level), level, true);
		} else if (fTraceMode)
			log(fMyLogger.getGenericMsg(fMyLogger.exceptionToString(t), level), level, false);
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(byte, java.util.logging.Level)
	 */
	public String log(boolean b, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(b), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(byte, java.util.logging.Level)
	 */
	public String log(byte b, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(b), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(char, java.util.logging.Level)
	 */
	public String log(char c, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(c), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(double, java.util.logging.Level)
	 */
	public String log(double d, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(d), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(float, java.util.logging.Level)
	 */
	public String log(float f, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(f), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(int, java.util.logging.Level)
	 */
	public String log(int i, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(i), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(long, java.util.logging.Level)
	 */
	public String log(long l, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(l), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(java.lang.Object, java.util.logging.Level)
	 */
	public String log(Object o, Level level) {
		if (o instanceof IStatus)
			return logWorkbench((IStatus) o, level);
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(o), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(short, java.util.logging.Level)
	 */
	public String log(short s, Level level) {
		if (level == DEFAULT)
			level = Level.FINEST;
		if (isLogging(level))
			return logWorkbench(fMyLogger.getGenericMsg(String.valueOf(s), level), level);
		else
			return NOLOG_DESCRIPTION;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.util.logger.proxy.ILogRenderer2#log(java.lang.Throwable, java.util.logging.Level)
	 */
	public String log(Throwable t, Level level) {
		if (t instanceof CoreException)
			return logWorkbench(((CoreException) t).getStatus(), level);
		if (level == DEFAULT)
			level = Level.SEVERE;
		if (isLogging(level)) {
			return logWorkbench(t, level);
		} else
			return NOLOG_DESCRIPTION;
	}

}