/*******************************************************************************
 * 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
 *******************************************************************************/
/*


 */
package org.eclipse.jem.util.logger.proxyrender;

import java.lang.reflect.Field;
import java.util.logging.Level;

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

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


/**
 * @deprecated Plugin error logging should be used instead
 * 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;
	static {
		String consologPropertyName = null;
		try {
			// Accessing an internal field, so using reflection. This way if changes in future we won't crash.
			Class eclipseStarter = Class.forName("org.eclipse.core.runtime.adaptor.EclipseStarter");	//$NON-NLS-1$
			Field consolelog = eclipseStarter.getDeclaredField("PROP_CONSOLE_LOG");	//$NON-NLS-1$
			consologPropertyName = (String) consolelog.get(null);
		} catch (SecurityException e) {
		} catch (IllegalArgumentException e) {
		} catch (ClassNotFoundException e) {
		} catch (NoSuchFieldException e) {
		} catch (IllegalAccessException e) {
		}
		consoleLogOn = consologPropertyName != null && "true".equals(System.getProperty(consologPropertyName)) ;  //$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 (Exception 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;
	}

}