/*
 * 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.jackrabbit.commons.observation;

import static java.lang.System.currentTimeMillis;
import static java.lang.System.nanoTime;
import static org.apache.jackrabbit.stats.TimeSeriesStatsUtil.asCompositeData;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.management.openmbean.CompositeData;

import org.apache.jackrabbit.api.jmx.EventListenerMBean;
import org.apache.jackrabbit.api.observation.JackrabbitEvent;
import org.apache.jackrabbit.commons.iterator.EventIteratorAdapter;
import org.apache.jackrabbit.stats.TimeSeriesMax;
import org.apache.jackrabbit.stats.TimeSeriesRecorder;

/**
 * Tracks event deliveries to an event listener and the way the listener
 * processes the events. The collected information is made available through
 * the {@link EventListenerMBean} interface.
 */
public class ListenerTracker {

    private final EventListener listener;

    private final int eventTypes;

    private final String absPath;

    private final boolean isDeep;

    private final String[] uuid;

    private final String[] nodeTypeName;

    private final boolean noLocal;

    protected final Exception initStackTrace =
            new Exception("The event listener was registered here:");

    private final long startTime = currentTimeMillis();

    private final AtomicLong eventDeliveries = new AtomicLong();

    private final AtomicLong eventsDelivered = new AtomicLong();

    private final AtomicLong eventDeliveryTime = new AtomicLong();

    private final AtomicLong headTimestamp = new AtomicLong();

    private final TimeSeriesMax queueLength = new TimeSeriesMax();

    private final TimeSeriesRecorder eventCount = new TimeSeriesRecorder(true);

    private final TimeSeriesRecorder eventConsumerTime = new TimeSeriesRecorder(true);

    private final TimeSeriesRecorder eventProducerTime = new TimeSeriesRecorder(true);

    final AtomicBoolean userInfoAccessedWithoutExternalsCheck =
            new AtomicBoolean();

    final AtomicBoolean userInfoAccessedFromExternalEvent =
            new AtomicBoolean();

    final AtomicBoolean dateAccessedWithoutExternalsCheck =
            new AtomicBoolean();

    final AtomicBoolean dateAccessedFromExternalEvent =
            new AtomicBoolean();

    public ListenerTracker(
            EventListener listener, int eventTypes, String absPath, boolean isDeep, String[] uuid,
            String[] nodeTypeName, boolean noLocal) {
        this.listener = listener;
        this.eventTypes = eventTypes;
        this.absPath = absPath;
        this.isDeep = isDeep;
        this.uuid = copy(uuid);
        this.nodeTypeName = copy(nodeTypeName);
        this.noLocal = noLocal;
    }

    /**
     * Called to log a deprecation warning about the detected behavior of
     * the decorated listener. Subclasses should override this method that
     * by default does nothing.
     *
     * @param message warning message
     */
    protected void warn(String message) {
        // do nothing
    }

    /**
     * Called just before the {@link EventListener#onEvent(EventIterator)}
     * method is called. The default implementation of this method does
     * nothing, but subclasses can override it to add custom processing.
     */
    protected void beforeEventDelivery() {
        // do nothing
    }

    /**
     * Called just after the {@link EventListener#onEvent(EventIterator)}
     * method has been called (even if the call threw an exception). The
     * default implementation of this method does nothing, but subclasses
     * can override it to add custom processing.
     */
    protected void afterEventDelivery() {
        // do nothing
    }

    /**
     * Applications should call this to report the current queue length.
     * @param length
     */
    public void recordQueueLength(long length) {
        queueLength.recordValue(length);
    }

    /**
     * Applications should call this to report the current queue length when an
     * item is removed from the queue.
     *
     * @param length        the length of the queue after the item was removed.
     * @param headTimestamp the time in milliseconds when the head item was
     *                      created and put into the queue.
     */
    public void recordQueueLength(long length, long headTimestamp) {
        queueLength.recordValue(length);
        this.headTimestamp.set(length == 0 ? 0 : headTimestamp);
    }

    /**
     * Records the number of measured values over the past second and resets
     * the counter. This method should be scheduled to be called once per
     * second.
     */
    public void recordOneSecond() {
        queueLength.recordOneSecond();
        eventCount.recordOneSecond();
        eventConsumerTime.recordOneSecond();
        eventProducerTime.recordOneSecond();
    }

    public EventListener getTrackedListener() {
        return new EventListener() {
            @Override
            public void onEvent(EventIterator events) {
                eventDeliveries.incrementAndGet();
                final long start = nanoTime();
                try {
                    beforeEventDelivery();
                    listener.onEvent(new EventIteratorAdapter(events) {
                        long t0 = start;

                        private void recordTime(TimeSeriesRecorder recorder) {
                            recorder.getCounter().addAndGet(-(t0 - (t0 = nanoTime())));
                        }

                        @Override
                        public Object next() {
                            recordTime(eventConsumerTime);
                            eventsDelivered.incrementAndGet();
                            eventCount.getCounter().incrementAndGet();
                            Object object = super.next();
                            if (object instanceof JackrabbitEvent) {
                                object = new JackrabbitEventTracker(
                                        ListenerTracker.this,
                                        (JackrabbitEvent) object);
                            } else if (object instanceof Event) {
                                object = new EventTracker(
                                        ListenerTracker.this, (Event) object);
                            }
                            recordTime(eventProducerTime);
                            return object;
                        }

                        @Override
                        public boolean hasNext() {
                            recordTime(eventConsumerTime);
                            boolean result = super.hasNext();
                            recordTime(eventProducerTime);
                            return result;
                        }
                    });
                } finally {
                    afterEventDelivery();
                    eventDeliveryTime.addAndGet(nanoTime() - start);
                }
            }

            @Override
            public String toString() {
                return ListenerTracker.this.toString();
            }
        };
    }

    public EventListenerMBean getListenerMBean() {
        return new EventListenerMBean() {
            @Override
            public String getClassName() {
                return listener.getClass().getName();
            }
            @Override
            public String getInitStackTrace() {
                StringWriter writer = new StringWriter();
                initStackTrace.printStackTrace(new PrintWriter(writer));
                return writer.toString();
            }
            @Override
            public int getEventTypes() {
                return eventTypes;
            }
            @Override
            public String getAbsPath() {
                return absPath;
            }
            @Override
            public boolean isDeep() {
                return isDeep;
            }
            @Override
            public String[] getUuid() {
                return copy(uuid);
            }
            @Override
            public String[] getNodeTypeName() {
                return copy(nodeTypeName);
            }
            @Override
            public boolean isNoLocal() {
                return noLocal;
            }
            @Override
            public long getEventDeliveries() {
                return eventDeliveries.get();
            }
            @Override
            public long getEventDeliveriesPerHour() {
                return TimeUnit.HOURS.toMillis(getEventDeliveries())
                        / Math.max(currentTimeMillis() - startTime, 1);
            }
            @Override
            public long getMicrosecondsPerEventDelivery() {
                return TimeUnit.NANOSECONDS.toMicros(eventDeliveryTime.get())
                        / Math.max(getEventDeliveries(), 1);
            }
            @Override
            public long getEventsDelivered() {
                return eventsDelivered.get();
            }
            @Override
            public long getEventsDeliveredPerHour() {
                return TimeUnit.HOURS.toMillis(getEventsDelivered())
                        / Math.max(currentTimeMillis() - startTime, 1);
            }
            @Override
            public long getMicrosecondsPerEventDelivered() {
                return TimeUnit.NANOSECONDS.toMicros(eventDeliveryTime.get())
                        / Math.max(getEventsDelivered(), 1);
            }
            @Override
            public double getRatioOfTimeSpentProcessingEvents() {
                double timeSpentProcessingEvents =
                        TimeUnit.NANOSECONDS.toMillis(eventDeliveryTime.get());
                return timeSpentProcessingEvents
                        / Math.max(currentTimeMillis() - startTime, 1);
            }
            @Override
            public double getEventConsumerTimeRatio() {
                double consumerTime = sum(eventConsumerTime.getValuePerSecond());
                double producerTime = sum(eventProducerTime.getValuePerSecond());
                return consumerTime / Math.max(consumerTime + producerTime, 1);
            }
            @Override
            public boolean isUserInfoAccessedWithoutExternalsCheck() {
                return userInfoAccessedWithoutExternalsCheck.get();
            }
            @Override
            public synchronized boolean isUserInfoAccessedFromExternalEvent() {
                return userInfoAccessedFromExternalEvent.get();
            }
            @Override
            public synchronized boolean isDateAccessedWithoutExternalsCheck() {
                return dateAccessedWithoutExternalsCheck.get();
            }
            @Override
            public synchronized boolean isDateAccessedFromExternalEvent() {
                return dateAccessedFromExternalEvent.get();
            }
            @Override
            public long getQueueBacklogMillis() {
                long t = headTimestamp.get();
                if (t > 0) {
                    t = currentTimeMillis() - t;
                }
                return t;
            }
            @Override
            public CompositeData getQueueLength() {
                return asCompositeData(queueLength, "queueLength");
            }
            @Override
            public CompositeData getEventCount() {
                return asCompositeData(eventCount, "eventCount");
            }
            @Override
            public CompositeData getEventConsumerTime() {
                return asCompositeData(eventConsumerTime, "eventConsumerTime");
            }
            @Override
            public CompositeData getEventProducerTime() {
                return asCompositeData(eventProducerTime, "eventProducerTime");
            }
        };
    }

    //------------------------------------------------------------< Object >--

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (absPath != null) {
            builder.append(absPath);
        }
        if (isDeep) {
            builder.append("//*");
        } else {
            builder.append("/*");
        }
        builder.append('[');
        builder.append(Integer.toBinaryString(eventTypes));
        builder.append('b');
        if (uuid != null) {
            for (String id : uuid) {
                builder.append(", ");
                builder.append(id);
            }
        }
        if (nodeTypeName != null) {
            for (String name : nodeTypeName) {
                builder.append(", ");
                builder.append(name);
            }
        }
        if (noLocal) {
            builder.append(", no local");
        }
        builder.append("]@");
        builder.append(listener.getClass().getName());
        return builder.toString();
    }

    //-----------------------------------------------------------< private >--

    private static String[] copy(String[] array) {
        if (array != null && array.length > 0) {
            String[] copy = new String[array.length];
            System.arraycopy(array, 0, copy, 0, array.length);
            return copy;
        } else {
            return array;
        }
    }

    private static long sum(long[] values) {
        long sum = 0;
        for (long v : values) {
            sum += v;
        }
        return sum;
    }

}
