/*******************************************************************************
 * Copyright (c) 2004, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import org.eclipse.core.runtime.adaptor.EclipseStarter;
import org.eclipse.equinox.log.ExtendedLogEntry;
import org.eclipse.equinox.log.LogFilter;
import org.eclipse.equinox.log.SynchronousLogListener;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.service.log.LogEntry;
import org.osgi.service.log.LogLevel;
import org.osgi.service.log.LogService;
import org.osgi.service.log.admin.LoggerAdmin;
import org.osgi.service.log.admin.LoggerContext;

class EquinoxLogWriter implements SynchronousLogListener, LogFilter {
	private static final String PASSWORD = "-password"; //$NON-NLS-1$	
	/** The session tag */
	private static final String SESSION = "!SESSION"; //$NON-NLS-1$
	/** The entry tag */
	private static final String ENTRY = "!ENTRY"; //$NON-NLS-1$
	/** The sub-entry tag */
	private static final String SUBENTRY = "!SUBENTRY"; //$NON-NLS-1$
	/** The message tag */
	private static final String MESSAGE = "!MESSAGE"; //$NON-NLS-1$
	/** The stacktrace tag */
	private static final String STACK = "!STACK"; //$NON-NLS-1$

	/** The line separator used in the log output */
	private static final String LINE_SEPARATOR;

	static {
		String s = System.getProperty("line.separator"); //$NON-NLS-1$
		LINE_SEPARATOR = s == null ? "\n" : s; //$NON-NLS-1$
	}

	//Constants for rotating log file
	/** The default size a log file can grow before it is rotated */
	private static final int DEFAULT_LOG_SIZE = 1000;
	/** The default number of backup log files */
	private static final int DEFAULT_LOG_FILES = 10;
	/** The minimum size limit for log rotation */
	private static final int LOG_SIZE_MIN = 10;

	/** The system property used to specify the log level */
	private static final String PROP_LOG_LEVEL = "eclipse.log.level"; //$NON-NLS-1$
	/** The system property used to specify size a log file can grow before it is rotated */
	private static final String PROP_LOG_SIZE_MAX = "eclipse.log.size.max"; //$NON-NLS-1$
	/** The system property used to specify the maximim number of backup log files to use */
	private static final String PROP_LOG_FILE_MAX = "eclipse.log.backup.max"; //$NON-NLS-1$
	/** The extension used for log files */
	private static final String LOG_EXT = ".log"; //$NON-NLS-1$
	/** The extension markup to use for backup log files*/
	private static final String BACKUP_MARK = ".bak_"; //$NON-NLS-1$

	/** The system property used to specify command line args should be omitted from the log */
	private static final String PROP_LOG_INCLUDE_COMMAND_LINE = "eclipse.log.include.commandline"; //$NON-NLS-1$
	/** Indicates if the console messages should be printed to the console (System.out) */
	private boolean consoleLog = false;
	/** Indicates if the next log message is part of a new session */
	private boolean newSession = true;
	/**
	 * The File object to store messages.  This value may be null.
	 */
	private File outFile;

	/**
	 * The Writer to log messages to.
	 */
	private Writer writer;

	private final String loggerName;
	private final boolean enabled;
	private final EquinoxConfiguration environmentInfo;

	int maxLogSize = DEFAULT_LOG_SIZE; // The value is in KB.
	int maxLogFiles = DEFAULT_LOG_FILES;
	int backupIdx = 0;

	private int logLevel = FrameworkLogEntry.OK;
	private boolean includeCommandLine = true;

	private LoggerAdmin loggerAdmin = null;

	/**
	 * Constructs an EclipseLog which uses the specified File to log messages to
	 * @param outFile a file to log messages to
	 */
	public EquinoxLogWriter(File outFile, String loggerName, boolean enabled, EquinoxConfiguration environmentInfo) {
		this.outFile = outFile;
		this.writer = null;
		this.loggerName = loggerName;
		this.enabled = enabled;
		this.environmentInfo = environmentInfo;
		readLogProperties();
	}

	/**
	 * Constructs an EclipseLog which uses the specified Writer to log messages to
	 * @param writer a writer to log messages to
	 */
	public EquinoxLogWriter(Writer writer, String loggerName, boolean enabled, EquinoxConfiguration environmentInfo) {
		if (writer == null)
			// log to System.err by default
			this.writer = logForErrorStream();
		else
			this.writer = writer;
		this.loggerName = loggerName;
		this.enabled = enabled;
		this.environmentInfo = environmentInfo;
	}

	private Throwable getRoot(Throwable t) {
		Throwable root = null;
		if (t instanceof BundleException)
			root = ((BundleException) t).getNestedException();
		if (t instanceof InvocationTargetException)
			root = ((InvocationTargetException) t).getTargetException();
		// skip inner InvocationTargetExceptions and BundleExceptions
		if (root instanceof InvocationTargetException || root instanceof BundleException) {
			Throwable deeplyNested = getRoot(root);
			if (deeplyNested != null)
				// if we have something more specific, use it, otherwise keep what we have
				root = deeplyNested;
		}
		return root;
	}

	/**
	 * Helper method for writing out argument arrays.
	 * @param header the header
	 * @param args the list of arguments
	 */
	private void writeArgs(String header, String[] args) throws IOException {
		if (args == null || args.length == 0)
			return;
		write(header);
		for (int i = 0; i < args.length; i++) {
			//mask out the password argument for security
			if (i > 0 && PASSWORD.equals(args[i - 1]))
				write(" (omitted)"); //$NON-NLS-1$
			else
				write(" " + args[i]); //$NON-NLS-1$
		}
		writeln();
	}

	/**
	 * Returns the session timestamp.  This is the time the platform was started
	 * @return the session timestamp
	 */
	private String getSessionTimestamp() {
		// Main should have set the session start-up timestamp so return that. 
		// Return the "now" time if not available.
		String ts = environmentInfo.getConfiguration("eclipse.startTime"); //$NON-NLS-1$
		if (ts != null) {
			try {
				return getDate(new Date(Long.parseLong(ts)));
			} catch (NumberFormatException e) {
				// fall through and use the timestamp from right now
			}
		}
		return getDate(new Date());
	}

	/**
	 * Writes the session
	 * @throws IOException if an error occurs writing to the log
	 */
	private void writeSession() throws IOException {
		write(SESSION);
		writeSpace();
		String date = getSessionTimestamp();
		write(date);
		writeSpace();
		for (int i = SESSION.length() + date.length(); i < 78; i++) {
			write("-"); //$NON-NLS-1$
		}
		writeln();
		// Write out certain values found in System.getProperties()
		try {
			String key = "eclipse.buildId"; //$NON-NLS-1$
			String value = environmentInfo.getConfiguration(key, "unknown"); //$NON-NLS-1$
			writeln(key + "=" + value); //$NON-NLS-1$

			key = "java.fullversion"; //$NON-NLS-1$
			value = System.getProperty(key);
			if (value == null) {
				key = "java.version"; //$NON-NLS-1$
				value = System.getProperty(key);
				writeln(key + "=" + value); //$NON-NLS-1$
				key = "java.vendor"; //$NON-NLS-1$
				value = System.getProperty(key);
				writeln(key + "=" + value); //$NON-NLS-1$
			} else {
				writeln(key + "=" + value); //$NON-NLS-1$
			}
		} catch (Exception e) {
			// If we're not allowed to get the values of these properties
			// then just skip over them.
		}
		// The Bootloader has some information that we might be interested in.
		write("BootLoader constants: OS=" + environmentInfo.getOS()); //$NON-NLS-1$
		write(", ARCH=" + environmentInfo.getOSArch()); //$NON-NLS-1$
		write(", WS=" + environmentInfo.getWS()); //$NON-NLS-1$
		writeln(", NL=" + environmentInfo.getNL()); //$NON-NLS-1$
		// Add the command-line arguments used to invoke the platform 
		// XXX: this includes runtime-private arguments - should we do that?
		if (includeCommandLine) {
			writeArgs("Framework arguments: ", environmentInfo.getNonFrameworkArgs()); //$NON-NLS-1$
			writeArgs("Command-line arguments: ", environmentInfo.getCommandLineArgs()); //$NON-NLS-1$
		}
	}

	public void close() {
		try {
			if (writer != null) {
				Writer tmpWriter = writer;
				writer = null;
				tmpWriter.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * If a File is used to log messages to then the File opened and a Writer is created
	 * to log messages to.
	 */
	private void openFile() {
		if (writer == null) {
			if (outFile != null) {
				try {
					writer = logForStream(ExtendedLogServiceFactory.secureAction.getFileOutputStream(outFile, true));
				} catch (IOException e) {
					writer = logForErrorStream();
				}
			} else {
				writer = logForErrorStream();
			}
		}
	}

	/**
	 * If a File is used to log messages to then the writer is closed.
	 */
	private void closeFile() {
		if (outFile != null) {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					// we cannot log here; just print the stacktrace.
					e.printStackTrace();
				}
				writer = null;
			}
		}
	}

	private synchronized void log(FrameworkLogEntry logEntry) {
		if (logEntry == null)
			return;
		if (!isLoggable(logEntry.getSeverity()))
			return;
		try {
			checkLogFileSize();
			openFile();
			if (newSession) {
				writeSession();
				newSession = false;
			}
			writeLog(0, logEntry);
			writer.flush();
		} catch (Exception e) {
			// any exceptions during logging should be caught 
			System.err.println("An exception occurred while writing to the platform log:");//$NON-NLS-1$
			e.printStackTrace(System.err);
			System.err.println("Logging to the console instead.");//$NON-NLS-1$
			//we failed to write, so dump log entry to console instead
			try {
				writer = logForErrorStream();
				writeLog(0, logEntry);
				writer.flush();
			} catch (Exception e2) {
				System.err.println("An exception occurred while logging to the console:");//$NON-NLS-1$
				e2.printStackTrace(System.err);
			}
		} finally {
			closeFile();
		}
	}

	public synchronized void setWriter(Writer newWriter, boolean append) {
		setOutput(null, newWriter, append);
	}

	/**
	 * @throws IOException  
	 */
	public synchronized void setFile(File newFile, boolean append) throws IOException {
		if (newFile != null && !newFile.equals(this.outFile)) {
			// If it's a new file, then reset.
			readLogProperties();
			backupIdx = 0;
		}
		setOutput(newFile, null, append);
		environmentInfo.setConfiguration(EclipseStarter.PROP_LOGFILE, newFile == null ? "" : newFile.getAbsolutePath()); //$NON-NLS-1$
	}

	synchronized void setLoggerAdmin(LoggerAdmin loggerAdmin) {
		this.loggerAdmin = loggerAdmin;
		applyLogLevel();
	}

	public synchronized File getFile() {
		return outFile;
	}

	public void setConsoleLog(boolean consoleLog) {
		this.consoleLog = consoleLog;
	}

	private void setOutput(File newOutFile, Writer newWriter, boolean append) {
		if (newOutFile == null || !newOutFile.equals(this.outFile)) {
			if (this.writer != null) {
				try {
					this.writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				this.writer = null;
			}
			// Append old outFile to newWriter. We only attempt to do this
			// if the current Writer is backed by a File and this is not
			// a new session.
			File oldOutFile = this.outFile;
			this.outFile = newOutFile;
			this.writer = newWriter;
			boolean copyFailed = false;
			if (append && oldOutFile != null && oldOutFile.isFile()) {
				Reader fileIn = null;
				try {
					openFile();
					fileIn = new InputStreamReader(ExtendedLogServiceFactory.secureAction.getFileInputStream(oldOutFile), "UTF-8"); //$NON-NLS-1$
					copyReader(fileIn, this.writer);
				} catch (IOException e) {
					copyFailed = true;
					e.printStackTrace();
				} finally {
					if (fileIn != null) {
						try {
							fileIn.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
						// delete the old file if copying didn't fail
						if (!copyFailed)
							oldOutFile.delete();
					}
					closeFile();
				}
			}
		}
	}

	private void copyReader(Reader reader, Writer aWriter) throws IOException {
		char buffer[] = new char[1024];
		int count;
		while ((count = reader.read(buffer, 0, buffer.length)) > 0) {
			aWriter.write(buffer, 0, count);
		}
	}

	/**
	 * Returns a date string using the correct format for the log.
	 * @param date the Date to format
	 * @return a date string.
	 */
	private String getDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		StringBuffer sb = new StringBuffer();
		appendPaddedInt(c.get(Calendar.YEAR), 4, sb).append('-');
		appendPaddedInt(c.get(Calendar.MONTH) + 1, 2, sb).append('-');
		appendPaddedInt(c.get(Calendar.DAY_OF_MONTH), 2, sb).append(' ');
		appendPaddedInt(c.get(Calendar.HOUR_OF_DAY), 2, sb).append(':');
		appendPaddedInt(c.get(Calendar.MINUTE), 2, sb).append(':');
		appendPaddedInt(c.get(Calendar.SECOND), 2, sb).append('.');
		appendPaddedInt(c.get(Calendar.MILLISECOND), 3, sb);
		return sb.toString();
	}

	private StringBuffer appendPaddedInt(int value, int pad, StringBuffer buffer) {
		pad = pad - 1;
		if (pad == 0)
			return buffer.append(Integer.toString(value));
		int padding = (int) Math.pow(10, pad);
		if (value >= padding)
			return buffer.append(Integer.toString(value));
		while (padding > value && padding > 1) {
			buffer.append('0');
			padding = padding / 10;
		}
		buffer.append(value);
		return buffer;
	}

	/**
	 * Returns a stacktrace string using the correct format for the log
	 * @param t the Throwable to get the stacktrace for
	 * @return a stacktrace string
	 */
	private String getStackTrace(Throwable t) {
		if (t == null)
			return null;

		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);

		t.printStackTrace(pw);
		// ensure the root exception is fully logged
		Throwable root = getRoot(t);
		if (root != null) {
			pw.println("Root exception:"); //$NON-NLS-1$
			root.printStackTrace(pw);
		}
		return sw.toString();
	}

	/**
	 * Returns a Writer for the given OutputStream
	 * @param output an OutputStream to use for the Writer
	 * @return a Writer for the given OutputStream
	 */
	private Writer logForStream(OutputStream output) {
		return new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
	}

	/**
	 * Always use the default encoding for System.err
	 */
	private Writer logForErrorStream() {
		return new BufferedWriter(new OutputStreamWriter(System.err));
	}

	/**
	 * Writes the log entry to the log using the specified depth.  A depth value of 0
	 * indicates that the log entry is the root entry.  Any value greater than 0 indicates
	 * a sub-entry.
	 * @param depth the depth of th entry
	 * @param entry the entry to log
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeLog(int depth, FrameworkLogEntry entry) throws IOException {
		writeEntry(depth, entry);
		writeMessage(entry);
		writeStack(entry);

		FrameworkLogEntry[] children = entry.getChildren();
		if (children != null) {
			for (FrameworkLogEntry child : children) {
				writeLog(depth + 1, child);
			}
		}
	}

	/**
	 * Writes the ENTRY or SUBENTRY header for an entry.  A depth value of 0
	 * indicates that the log entry is the root entry.  Any value greater than 0 indicates
	 * a sub-entry.
	 * @param depth the depth of th entry
	 * @param entry the entry to write the header for
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeEntry(int depth, FrameworkLogEntry entry) throws IOException {
		if (depth == 0) {
			writeln(); // write a blank line before all !ENTRY tags bug #64406
			write(ENTRY);
		} else {
			write(SUBENTRY);
			writeSpace();
			write(Integer.toString(depth));
		}
		writeSpace();
		write(entry.getEntry());
		writeSpace();
		write(Integer.toString(entry.getSeverity()));
		writeSpace();
		write(Integer.toString(entry.getBundleCode()));
		writeSpace();
		write(getDate(new Date()));
		writeln();
	}

	/**
	 * Writes the MESSAGE header to the log for the given entry.
	 * @param entry the entry to write the message for
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeMessage(FrameworkLogEntry entry) throws IOException {
		write(MESSAGE);
		writeSpace();
		writeln(entry.getMessage());
	}

	/**
	 * Writes the STACK header to the log for the given entry.
	 * @param entry the entry to write the stacktrace for
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeStack(FrameworkLogEntry entry) throws IOException {
		Throwable t = entry.getThrowable();
		if (t != null) {
			String stack = getStackTrace(t);
			write(STACK);
			writeSpace();
			write(Integer.toString(entry.getStackCode()));
			writeln();
			write(stack);
		}
	}

	/**
	 * Writes the given message to the log.
	 * @param message the message
	 * @throws IOException if any error occurs writing to the log
	 */
	private void write(String message) throws IOException {
		if (message != null) {
			writer.write(message);
			if (consoleLog)
				System.out.print(message);
		}
	}

	/**
	 * Writes the given message to the log and a newline.
	 * @param s the message
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeln(String s) throws IOException {
		write(s);
		writeln();
	}

	/**
	 * Writes a newline log.
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeln() throws IOException {
		write(LINE_SEPARATOR);
	}

	/**
	 * Writes a space to the log.
	 * @throws IOException if any error occurs writing to the log
	 */
	private void writeSpace() throws IOException {
		write(" "); //$NON-NLS-1$
	}

	/**
	 * Checks the log file size.  If the log file size reaches the limit then the log 
	 * is rotated
	 * @return false if an error occured trying to rotate the log
	 */
	private boolean checkLogFileSize() {
		if (maxLogSize == 0)
			return true; // no size limitation.

		boolean isBackupOK = true;
		if (outFile != null) {
			if ((ExtendedLogServiceFactory.secureAction.length(outFile) >> 10) > maxLogSize) { // Use KB as file size unit.
				String logFilename = outFile.getAbsolutePath();

				// Delete old backup file that will be replaced.
				String backupFilename = ""; //$NON-NLS-1$
				if (logFilename.toLowerCase().endsWith(LOG_EXT)) {
					backupFilename = logFilename.substring(0, logFilename.length() - LOG_EXT.length()) + BACKUP_MARK + backupIdx + LOG_EXT;
				} else {
					backupFilename = logFilename + BACKUP_MARK + backupIdx;
				}
				File backupFile = new File(backupFilename);
				if (backupFile.exists()) {
					if (!backupFile.delete()) {
						System.err.println("Error when trying to delete old log file: " + backupFile.getName());//$NON-NLS-1$ 
						if (backupFile.renameTo(new File(backupFile.getAbsolutePath() + System.currentTimeMillis()))) {
							System.err.println("So we rename it to filename: " + backupFile.getName()); //$NON-NLS-1$
						} else {
							System.err.println("And we also cannot rename it!"); //$NON-NLS-1$
							isBackupOK = false;
						}
					}
				}

				// Rename current log file to backup one.
				boolean isRenameOK = outFile.renameTo(backupFile);
				if (!isRenameOK) {
					System.err.println("Error when trying to rename log file to backup one."); //$NON-NLS-1$
					isBackupOK = false;
				}
				File newFile = new File(logFilename);
				setOutput(newFile, null, false);

				// Write a new SESSION header to new log file.
				openFile();
				try {
					writeSession();
					writeln();
					writeln("This is a continuation of log file " + backupFile.getAbsolutePath());//$NON-NLS-1$
					writeln("Created Time: " + getDate(new Date(System.currentTimeMillis()))); //$NON-NLS-1$
					writer.flush();
				} catch (IOException ioe) {
					ioe.printStackTrace(System.err);
				}
				closeFile();
				backupIdx = (++backupIdx) % maxLogFiles;
			}
		}
		return isBackupOK;
	}

	/**
	 * Reads the PROP_LOG_SIZE_MAX and PROP_LOG_FILE_MAX properties.
	 */
	private void readLogProperties() {
		String newMaxLogSize = environmentInfo.getConfiguration(PROP_LOG_SIZE_MAX);
		if (newMaxLogSize != null) {
			maxLogSize = Integer.parseInt(newMaxLogSize);
			if (maxLogSize != 0 && maxLogSize < LOG_SIZE_MIN) {
				// If the value is '0', then it means no size limitation.
				// Also, make sure no inappropriate(too small) assigned value.
				maxLogSize = LOG_SIZE_MIN;
			}
		}

		String newMaxLogFiles = environmentInfo.getConfiguration(PROP_LOG_FILE_MAX);
		if (newMaxLogFiles != null) {
			maxLogFiles = Integer.parseInt(newMaxLogFiles);
			if (maxLogFiles < 1) {
				// Make sure no invalid assigned value. (at least >= 1)
				maxLogFiles = DEFAULT_LOG_FILES;
			}
		}

		String newLogLevel = environmentInfo.getConfiguration(PROP_LOG_LEVEL);
		if (newLogLevel != null) {
			if (newLogLevel.equals("ERROR")) //$NON-NLS-1$
				logLevel = FrameworkLogEntry.ERROR;
			else if (newLogLevel.equals("WARNING")) //$NON-NLS-1$
				logLevel = FrameworkLogEntry.ERROR | FrameworkLogEntry.WARNING;
			else if (newLogLevel.equals("INFO")) //$NON-NLS-1$
				logLevel = FrameworkLogEntry.INFO | FrameworkLogEntry.ERROR | FrameworkLogEntry.WARNING | FrameworkLogEntry.CANCEL;
			else
				logLevel = FrameworkLogEntry.OK; // OK (0) means log everything
		}

		includeCommandLine = "true".equals(environmentInfo.getConfiguration(PROP_LOG_INCLUDE_COMMAND_LINE, "true")); //$NON-NLS-1$//$NON-NLS-2$
		applyLogLevel();
	}

	void applyLogLevel() {
		if (loggerAdmin == null) {
			return;
		}
		LoggerContext rootContext = loggerAdmin.getLoggerContext(null);
		Map<String, LogLevel> rootLevels = rootContext.getLogLevels();
		rootLevels.put(loggerName, getLogLevel());
		rootContext.setLogLevels(rootLevels);
	}

	private LogLevel getLogLevel() {
		if (logLevel == 0) {
			return LogLevel.TRACE;
		}
		if ((logLevel & FrameworkLogEntry.INFO) != 0) {
			return LogLevel.INFO;
		}
		if ((logLevel & FrameworkLogEntry.WARNING) != 0) {
			return LogLevel.WARN;
		}
		if ((logLevel & FrameworkLogEntry.ERROR) != 0) {
			return LogLevel.ERROR;
		}
		// not sure what to do here; it seems it would be an error
		return LogLevel.AUDIT;
	}

	/**
	 * Determines if the log entry should be logged based on log level.
	 */
	private boolean isLoggable(int fwkEntrySeverity) {
		if (logLevel == 0)
			return true;
		return (fwkEntrySeverity & logLevel) != 0;
	}

	@SuppressWarnings("deprecation")
	@Override
	public boolean isLoggable(Bundle bundle, String loggableName, int loggableLevel) {
		if (!enabled)
			return false;
		if (loggerName.equals(loggableName))
			return isLoggable(convertSeverity(loggableLevel));
		if (EquinoxLogServices.PERF_LOGGER_NAME.equals(loggableName))
			// we don't want to do anything with performance logger unless
			// this is the performance logger (check done above).
			return false;
		if (!EquinoxLogServices.EQUINOX_LOGGER_NAME.equals(loggerName))
			// only the equinox log writer should pay attention to other logs
			return false;
		// for now only log errors; probably need this to be configurable
		return loggableLevel == LogService.LOG_ERROR;
	}

	@SuppressWarnings("deprecation")
	@Override
	public void logged(LogEntry entry) {
		if (!(entry instanceof ExtendedLogEntry))
			// TODO this should never happen
			return;
		ExtendedLogEntry extended = (ExtendedLogEntry) entry;
		Object context = extended.getContext();
		if (context instanceof FrameworkLogEntry) {
			log((FrameworkLogEntry) context);
			return;
		}
		// OK we are now in a case where someone logged a normal entry to the real LogService
		log(new FrameworkLogEntry(getFwkEntryTag(entry), convertSeverity(entry.getLevel()), 0, entry.getMessage(), 0, entry.getException(), null));
	}

	private static String getFwkEntryTag(LogEntry entry) {
		Bundle b = entry.getBundle();
		if (b != null && b.getSymbolicName() != null)
			return b.getSymbolicName();
		return "unknown"; //$NON-NLS-1$
	}

	@SuppressWarnings("deprecation")
	private static int convertSeverity(int entryLevel) {
		switch (entryLevel) {
			case LogService.LOG_ERROR :
				return FrameworkLogEntry.ERROR;
			case LogService.LOG_WARNING :
				return FrameworkLogEntry.WARNING;
			case LogService.LOG_INFO :
				return FrameworkLogEntry.INFO;
			case LogService.LOG_DEBUG :
				return FrameworkLogEntry.OK;
			default :
				return 32; // unknown
		}
	}

	public String getLoggerName() {
		return loggerName;
	}
}
