/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 */

package org.apache.log4j.lf5;

import org.apache.log4j.lf5.util.Resource;
import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;

import java.awt.*;

/**
 * <code>LF5Appender</code> logs events to a swing based logging
 * console. The swing console supports turning categories on and off,
 * multiple detail level views, as well as full text searching and many
 * other capabilties.
 *
 * @author Brent Sprecher
 */

// Contributed by ThoughtWorks Inc.

public class LF5Appender extends AppenderSkeleton {
  //--------------------------------------------------------------------------
  // Constants:
  //--------------------------------------------------------------------------

  //--------------------------------------------------------------------------
  // Protected Variables:
  //--------------------------------------------------------------------------

  protected LogBrokerMonitor _logMonitor;
  protected static LogBrokerMonitor _defaultLogMonitor;
  protected static AppenderFinalizer _finalizer;

  //--------------------------------------------------------------------------
  // Private Variables:
  //--------------------------------------------------------------------------

  //--------------------------------------------------------------------------
  // Constructors:
  //--------------------------------------------------------------------------

  /**
   * Constructs a <code>LF5Appender</code> using the default instance of
   * the <code>LogBrokerMonitor</code>. This constructor should <bold>always
   * </bold> be  preferred over the
   * <code>LF5Appender(LogBrokerMonitor monitor)</code>
   * constructor, unless you need to spawn additional log monitoring
   * windows.
   */
  public LF5Appender() {
    this(getDefaultInstance());
  }

  /**
   * Constructs a <code>LF5Appender<code> using an instance of
   * a <code>LogBrokerMonitor<code> supplied by the user. This
   * constructor should only be used when you need to spawn
   * additional log monitoring windows.
   *
   * @param monitor An instance of a <code>LogBrokerMonitor<code>
   * created by the user.
   */
  public LF5Appender(LogBrokerMonitor monitor) {

    if (monitor != null) {
      _logMonitor = monitor;
    }
  }

  //--------------------------------------------------------------------------
  // Public Methods:
  //--------------------------------------------------------------------------

  /**
   * Appends a <code>LoggingEvent</code> record to the
   * <code>LF5Appender</code>.
   * @param event The <code>LoggingEvent</code>
   * to be appended.
   */
  public void append(LoggingEvent event) {
    // Retrieve the information from the log4j LoggingEvent.
    String category = event.getLoggerName();
    String logMessage = event.getRenderedMessage();
    String nestedDiagnosticContext = event.getNDC();
    String threadDescription = event.getThreadName();
    String level = event.getLevel().toString();
    long time = event.timeStamp;
    LocationInfo locationInfo = event.getLocationInformation();

    // Add the logging event information to a LogRecord
    Log4JLogRecord record = new Log4JLogRecord();

    record.setCategory(category);
    record.setMessage(logMessage);
    record.setLocation(locationInfo.fullInfo);
    record.setMillis(time);
    record.setThreadDescription(threadDescription);

    if (nestedDiagnosticContext != null) {
      record.setNDC(nestedDiagnosticContext);
    } else {
      record.setNDC("");
    }

    if (event.getThrowableInformation() != null) {
      record.setThrownStackTrace(event.getThrowableInformation());
    }

    try {
      record.setLevel(LogLevel.valueOf(level));
    } catch (LogLevelFormatException e) {
      // If the priority level doesn't match one of the predefined
      // log levels, then set the level to warning.
      record.setLevel(LogLevel.WARN);
    }

    if (_logMonitor != null) {
      _logMonitor.addMessage(record);
    }
  }

  /**
   * This method is an empty implementation of the close() method inherited
   * from the <code>org.apache.log4j.Appender</code> interface.
   */
  public void close() {
  }

  /**
   * Returns a value that indicates whether this appender requires a
   * <code>Layout</code>. This method always returns false.
   * No layout is required for the <code>LF5Appender</code>.
   */
  public boolean requiresLayout() {
    return false;
  }

  /**
   * This method is used to set the property that controls whether
   * the <code>LogBrokerMonitor</code> is hidden or closed when a user
   * exits
   * the monitor. By default, the <code>LogBrokerMonitor</code> will hide
   * itself when the log window is exited, and the swing thread will
   * continue to run in the background. If this property is
   * set to true, the <code>LogBrokerMonitor</code> will call System.exit(0)
   * and will shut down swing thread and the virtual machine.
   *
   * @param callSystemExitOnClose A boolean value indicating whether
   * to call System.exit(0) when closing the log window.
   */
  public void setCallSystemExitOnClose(boolean callSystemExitOnClose) {
    _logMonitor.setCallSystemExitOnClose(callSystemExitOnClose);
  }

  /**
   * The equals method compares two LF5Appenders and determines whether
   * they are equal. Two <code>Appenders</code> will be considered equal
   * if, and only if, they both contain references to the same <code>
   * LogBrokerMonitor</code>.
   *
   * @param compareTo A boolean value indicating whether
   * the two LF5Appenders are equal.
   */
  public boolean equals(LF5Appender compareTo) {
    // If both reference the same LogBrokerMonitor, they are equal.
    return _logMonitor == compareTo.getLogBrokerMonitor();
  }

  public LogBrokerMonitor getLogBrokerMonitor() {
    return _logMonitor;
  }

  public static void main(String[] args) {
    new LF5Appender();
  }

  public void setMaxNumberOfRecords(int maxNumberOfRecords) {
    _defaultLogMonitor.setMaxNumberOfLogRecords(maxNumberOfRecords);
  }
  //--------------------------------------------------------------------------
  // Protected Methods:
  //--------------------------------------------------------------------------

  /**
   * @return The default instance of the <code>LogBrokerMonitor</code>.
   */
  protected static synchronized LogBrokerMonitor getDefaultInstance() {
    if (_defaultLogMonitor == null) {
      try {
        _defaultLogMonitor =
            new LogBrokerMonitor(LogLevel.getLog4JLevels());
        _finalizer = new AppenderFinalizer(_defaultLogMonitor);

        _defaultLogMonitor.setFrameSize(getDefaultMonitorWidth(),
            getDefaultMonitorHeight());
        _defaultLogMonitor.setFontSize(12);
        _defaultLogMonitor.show();

      } catch (SecurityException e) {
        _defaultLogMonitor = null;
      }
    }

    return _defaultLogMonitor;
  }

  /**
   * @return the screen width from Toolkit.getScreenSize()
   * if possible, otherwise returns 800
   * @see java.awt.Toolkit
   */
  protected static int getScreenWidth() {
    try {
      return Toolkit.getDefaultToolkit().getScreenSize().width;
    } catch (Throwable t) {
      return 800;
    }
  }

  /**
   * @return the screen height from Toolkit.getScreenSize()
   * if possible, otherwise returns 600
   * @see java.awt.Toolkit
   */
  protected static int getScreenHeight() {
    try {
      return Toolkit.getDefaultToolkit().getScreenSize().height;
    } catch (Throwable t) {
      return 600;
    }
  }

  protected static int getDefaultMonitorWidth() {
    return (3 * getScreenWidth()) / 4;
  }

  protected static int getDefaultMonitorHeight() {
    return (3 * getScreenHeight()) / 4;
  }
  //--------------------------------------------------------------------------
  // Private Methods:
  //--------------------------------------------------------------------------


  //--------------------------------------------------------------------------
  // Nested Top-Level Classes or Interfaces:
  //--------------------------------------------------------------------------

}
