/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.log4j.chainsaw;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.event.EventListenerList;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.LogManager;
import org.apache.log4j.helpers.Constants;
import org.apache.log4j.net.SocketReceiver;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LoggerRepositoryEx;
import org.apache.log4j.spi.LoggingEventFieldResolver;

/**
 * A handler class that either extends a particular appender hierarchy or can be
 * bound into the Log4j appender framework, and queues events, to be later
 * dispatched to registered/interested parties.
 * 
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 * @author Paul Smith &lt;psmith@apache.org&gt;
 * 
 */
public class ChainsawAppenderHandler extends AppenderSkeleton {
  private static final String DEFAULT_IDENTIFIER = "Unknown";
  private final Object mutex = new Object();
  private int sleepInterval = 1000;
  private EventListenerList listenerList = new EventListenerList();
  private double dataRate = 0.0;
  private String identifierExpression;
  private final LoggingEventFieldResolver resolver = LoggingEventFieldResolver
      .getInstance();
  private PropertyChangeSupport propertySupport = new PropertyChangeSupport(
      this);
  private Map customExpressionRules = new HashMap();

  /**
   * NOTE: This variable needs to be physically located LAST, because
   * of the initialization sequence, the WorkQueue constructor starts a thread 
   * which ends up needing some reference to fields created in ChainsawAppenderHandler (outer instance)
   * which may not have been created yet.  Becomes a race condition, and therefore
   * this field initialization should be kept last.
   */
  private WorkQueue worker = new WorkQueue();
  
  public ChainsawAppenderHandler(final ChainsawAppender appender) {
    super(true);
    appender.setAppender(this);
  }

  public ChainsawAppenderHandler() {
    super(true);
  }

  public void setIdentifierExpression(String identifierExpression) {
    synchronized (mutex) {
      this.identifierExpression = identifierExpression;
      mutex.notify();
    }
  }

  public String getIdentifierExpression() {
    return identifierExpression;
  }

  public void addCustomEventBatchListener(String identifier,
      EventBatchListener l) throws IllegalArgumentException {
    customExpressionRules.put(identifier, ExpressionRule.getRule(identifier));
    listenerList.add(EventBatchListener.class, l);
  }

  public void addEventBatchListener(EventBatchListener l) {
    listenerList.add(EventBatchListener.class, l);
  }

  public void removeEventBatchListener(EventBatchListener l) {
    listenerList.remove(EventBatchListener.class, l);
  }

  public void append(LoggingEvent event) {
    worker.enqueue(event);
  }

  public void close() {}

  public boolean requiresLayout() {
    return false;
  }

  public int getQueueInterval() {
    return sleepInterval;
  }

  public void setQueueInterval(int interval) {
    sleepInterval = interval;
  }

  /**
   * Determines an appropriate title for the Tab for the Tab Pane by locating a
   * the hostname property
   * 
   * @param e
   * @return identifier
   */
  String getTabIdentifier(LoggingEvent e) {
    String ident = resolver.applyFields(identifierExpression, e);
    return ((ident != null) ? ident : DEFAULT_IDENTIFIER);
  }

  /**
   * A little test bed
   * 
   * @param args
   */
  public static void main(String[] args) throws InterruptedException {
    ChainsawAppenderHandler handler = new ChainsawAppenderHandler();
    handler.addEventBatchListener(new EventBatchListener() {
      public String getInterestedIdentifier() {
        return null;
      }

      public void receiveEventBatch(String identifier, List events) {
        System.out.println("received " + events.size());
      }
    });
    LogManager.getRootLogger().addAppender(handler);
    SocketReceiver receiver = new SocketReceiver(4445);
    ((LoggerRepositoryEx) LogManager.getLoggerRepository()).getPluginRegistry().addPlugin(receiver);
    receiver.activateOptions();
    Thread.sleep(60000);
  }

  /**
   * Exposes the current Data rate calculated. This is periodically updated by
   * an internal Thread as is the number of events that have been processed, and
   * dispatched to all listeners since the last sample period divided by the
   * number of seconds since the last sample period.
   * 
   * This method fires a PropertyChange event so listeners can monitor the rate
   * 
   * @return double # of events processed per second
   */
  public double getDataRate() {
    return dataRate;
  }

  /**
   * @param dataRate
   */
  void setDataRate(double dataRate) {
    double oldValue = this.dataRate;
    this.dataRate = dataRate;
    propertySupport.firePropertyChange("dataRate", oldValue,
            this.dataRate);
  }

  /**
   * @param listener
   */
  public synchronized void addPropertyChangeListener(
      PropertyChangeListener listener) {
    propertySupport.addPropertyChangeListener(listener);
  }

  /**
   * @param propertyName
   * @param listener
   */
  public synchronized void addPropertyChangeListener(String propertyName,
      PropertyChangeListener listener) {
    propertySupport.addPropertyChangeListener(propertyName, listener);
  }

  /**
   * @param listener
   */
  public synchronized void removePropertyChangeListener(
      PropertyChangeListener listener) {
    propertySupport.removePropertyChangeListener(listener);
  }

  /**
   * @param propertyName
   * @param listener
   */
  public synchronized void removePropertyChangeListener(String propertyName,
      PropertyChangeListener listener) {
    propertySupport.removePropertyChangeListener(propertyName, listener);
  }

  /**
   * Queue of Events are placed in here, which are picked up by an asychronous
   * thread. The WorkerThread looks for events once a second and processes all
   * events accumulated during that time..
   */
  class WorkQueue {
    final ArrayList queue = new ArrayList();
    Thread workerThread;

    protected WorkQueue() {
      workerThread = new WorkerThread();
      workerThread.start();
    }

    public final void enqueue(LoggingEvent event) {
      synchronized (mutex) {
        queue.add(event);
        mutex.notify();
      }
    }

    public final void stop() {
      synchronized (mutex) {
        workerThread.interrupt();
      }
    }

    /**
     * The worker thread converts each queued event to a vector and forwards the
     * vector on to the UI.
     */
    private class WorkerThread extends Thread {
      public WorkerThread() {
        super("Chainsaw-WorkerThread");
        setDaemon(true);
        setPriority(Thread.NORM_PRIORITY - 1);
      }

      public void run() {
        List innerList = new ArrayList();
        while (true) {
          long timeStart = System.currentTimeMillis();
          synchronized (mutex) {
            try {
              while ((queue.size() == 0) || (identifierExpression == null)) {
                setDataRate(0);
                mutex.wait();
              }
              if (queue.size() > 0) {
                innerList.addAll(queue);
                queue.clear();
              }
            }
            catch (InterruptedException ie) {}
          }
          int size = innerList.size();
          if (size > 0) {
            Iterator iter = innerList.iterator();
            ChainsawEventBatch eventBatch = new ChainsawEventBatch();
            while (iter.hasNext()) {
              LoggingEvent e = (LoggingEvent) iter.next();
              // attempt to set the host name (without port), from
              // remoteSourceInfo
              // if 'hostname' property not provided
              if (e.getProperty(Constants.HOSTNAME_KEY) == null) {
                String remoteHost = e
                    .getProperty(ChainsawConstants.LOG4J_REMOTEHOST_KEY);
                if (remoteHost != null) {
                  int colonIndex = remoteHost.indexOf(":");
                  if (colonIndex == -1) {
                    colonIndex = remoteHost.length();
                  }
                  e.setProperty(Constants.HOSTNAME_KEY, remoteHost.substring(0,
                      colonIndex));
                }
              }
              for (Object o : customExpressionRules.entrySet()) {
                Map.Entry entry = (Map.Entry) o;
                Rule rule = (Rule) entry.getValue();
                if (rule.evaluate(e, null)) {
                  eventBatch.addEvent((String) entry.getKey(), e);
                }
              }
              eventBatch.addEvent(getTabIdentifier(e), e);
            }
            dispatchEventBatch(eventBatch);
            innerList.clear();
          }
          if (getQueueInterval() > 1000) {
            try {
              synchronized (this) {
                wait(getQueueInterval());
              }
            }
            catch (InterruptedException ie) {}
          } else {
            Thread.yield();
          }
          if (size == 0) {
            setDataRate(0.0);
          } else {
            long timeEnd = System.currentTimeMillis();
            long diffInSeconds = (timeEnd - timeStart) / 1000;
            double rate = (((double) size) / diffInSeconds);
            setDataRate(rate);
          }
        }
      }

      /**
       * Dispatches the event batches contents to all the interested parties by
       * iterating over each identifier and dispatching the
       * ChainsawEventBatchEntry object to each listener that is interested.
       * 
       * @param eventBatch
       */
      private void dispatchEventBatch(ChainsawEventBatch eventBatch) {
        EventBatchListener[] listeners = listenerList
            .getListeners(EventBatchListener.class);
        for (Iterator iter = eventBatch.identifierIterator(); iter.hasNext();) {
          String identifier = (String) iter.next();
          List eventList = null;
          for (EventBatchListener listener : listeners) {
            if ((listener.getInterestedIdentifier() == null)
                    || listener.getInterestedIdentifier().equals(identifier)) {
              if (eventList == null) {
                eventList = eventBatch.entrySet(identifier);
              }
              listener.receiveEventBatch(identifier, eventList);
            }
          }
        }
      }
    }
  }
}
