/*
 *  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.mina.filter.statistic;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoEventType;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;

/**
 * This class will measure the time it takes for a method in the {@link IoFilterAdapter} class to execute. The basic
 * premise of the logic in this class is to get the current time at the beginning of the method, call method on
 * nextFilter, and then get the current time again. An example of how to use the filter is:
 *
 * <pre>
 * ProfilerTimerFilter profiler = new ProfilerTimerFilter(TimeUnit.MILLISECOND, IoEventType.MESSAGE_RECEIVED);
 * chain.addFirst("Profiler", profiler);
 * </pre>
 * 
 * The profiled {@link IoEventType} are :
 * <ul>
 * <li>IoEventType.MESSAGE_RECEIVED</li>
 * <li>IoEventType.MESSAGE_SENT</li>
 * <li>IoEventType.SESSION_CREATED</li>
 * <li>IoEventType.SESSION_OPENED</li>
 * <li>IoEventType.SESSION_IDLE</li>
 * <li>IoEventType.SESSION_CLOSED</li>
 * </ul>
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 * @org.apache.xbean.XBean
 */
public class ProfilerTimerFilter extends IoFilterAdapter {
    /** TRhe selected time unit */
    private volatile TimeUnit timeUnit;

    /** A TimerWorker for the MessageReceived events */
    private TimerWorker messageReceivedTimerWorker;

    /** A flag to tell the filter that the MessageReceived must be profiled */
    private boolean profileMessageReceived = false;

    /** A TimerWorker for the MessageSent events */
    private TimerWorker messageSentTimerWorker;

    /** A flag to tell the filter that the MessageSent must be profiled */
    private boolean profileMessageSent = false;

    /** A TimerWorker for the SessionCreated events */
    private TimerWorker sessionCreatedTimerWorker;

    /** A flag to tell the filter that the SessionCreated must be profiled */
    private boolean profileSessionCreated = false;

    /** A TimerWorker for the SessionOpened events */
    private TimerWorker sessionOpenedTimerWorker;

    /** A flag to tell the filter that the SessionOpened must be profiled */
    private boolean profileSessionOpened = false;

    /** A TimerWorker for the SessionIdle events */
    private TimerWorker sessionIdleTimerWorker;

    /** A flag to tell the filter that the SessionIdle must be profiled */
    private boolean profileSessionIdle = false;

    /** A TimerWorker for the SessionClosed events */
    private TimerWorker sessionClosedTimerWorker;

    /** A flag to tell the filter that the SessionClosed must be profiled */
    private boolean profileSessionClosed = false;

    /**
     * Creates a new instance of ProfilerFilter. This is the default constructor and will print out timings for
     * messageReceived and messageSent and the time increment will be in milliseconds.
     */
    public ProfilerTimerFilter() {
        this(TimeUnit.MILLISECONDS, IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
    }

    /**
     * Creates a new instance of ProfilerFilter. This is the default constructor and will print out timings for
     * messageReceived and messageSent.
     * 
     * @param timeUnit
     *            the time increment to set
     */
    public ProfilerTimerFilter(TimeUnit timeUnit) {
        this(timeUnit, IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
    }

    /**
     * Creates a new instance of ProfilerFilter. An example of this call would be:
     *
     * <pre>
     * new ProfilerTimerFilter(TimeUnit.MILLISECONDS, IoEventType.MESSAGE_RECEIVED, IoEventType.MESSAGE_SENT);
     * </pre>
     * 
     * Note : you can add as many {@link IoEventType} as you want. The method accepts a variable number of arguments.
     * 
     * @param timeUnit
     *            Used to determine the level of precision you need in your timing.
     * @param eventTypes
     *            A list of {@link IoEventType} representation of the methods to profile
     */
    public ProfilerTimerFilter(TimeUnit timeUnit, IoEventType... eventTypes) {
        this.timeUnit = timeUnit;

        setProfilers(eventTypes);
    }

    /**
     * Create the profilers for a list of {@link IoEventType}.
     * 
     * @param eventTypes
     *            the list of {@link IoEventType} to profile
     */
    private void setProfilers(IoEventType... eventTypes) {
        for (IoEventType type : eventTypes) {
            switch (type) {
                case MESSAGE_RECEIVED:
                    messageReceivedTimerWorker = new TimerWorker();
                    profileMessageReceived = true;
                    break;
            
                case MESSAGE_SENT:
                    messageSentTimerWorker = new TimerWorker();
                    profileMessageSent = true;
                    break;
            
                case SESSION_CREATED:
                    sessionCreatedTimerWorker = new TimerWorker();
                    profileSessionCreated = true;
                    break;
            
                case SESSION_OPENED:
                    sessionOpenedTimerWorker = new TimerWorker();
                    profileSessionOpened = true;
                    break;
            
                case SESSION_IDLE:
                    sessionIdleTimerWorker = new TimerWorker();
                    profileSessionIdle = true;
                    break;
            
                case SESSION_CLOSED:
                    sessionClosedTimerWorker = new TimerWorker();
                    profileSessionClosed = true;
                    break;
            
                default:
                    break;
            }
        }
    }

    /**
     * Sets the {@link TimeUnit} being used.
     *
     * @param timeUnit
     *            the new {@link TimeUnit} to be used.
     */
    public void setTimeUnit(TimeUnit timeUnit) {
        this.timeUnit = timeUnit;
    }

    /**
     * Set the {@link IoEventType} to be profiled
     *
     * @param type
     *            The {@link IoEventType} to profile
     */
    public void profile(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                profileMessageReceived = true;
            
                if (messageReceivedTimerWorker == null) {
                    messageReceivedTimerWorker = new TimerWorker();
                }
            
                return;
            
            case MESSAGE_SENT:
                profileMessageSent = true;
            
                if (messageSentTimerWorker == null) {
                    messageSentTimerWorker = new TimerWorker();
                }
            
                return;
            
            case SESSION_CREATED:
                profileSessionCreated = true;
            
                if (sessionCreatedTimerWorker == null) {
                    sessionCreatedTimerWorker = new TimerWorker();
                }
            
                return;
            
            case SESSION_OPENED:
                profileSessionOpened = true;
            
                if (sessionOpenedTimerWorker == null) {
                    sessionOpenedTimerWorker = new TimerWorker();
                }
            
                return;
            
            case SESSION_IDLE:
                profileSessionIdle = true;
            
                if (sessionIdleTimerWorker == null) {
                    sessionIdleTimerWorker = new TimerWorker();
                }
            
                return;
            
            case SESSION_CLOSED:
                profileSessionClosed = true;
            
                if (sessionClosedTimerWorker == null) {
                    sessionClosedTimerWorker = new TimerWorker();
                }
            
                return;
            
            default:
                break;
        }
    }

    /**
     * Stop profiling an {@link IoEventType}
     *
     * @param type
     *            The {@link IoEventType} to stop profiling
     */
    public void stopProfile(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                profileMessageReceived = false;
                return;
            
            case MESSAGE_SENT:
                profileMessageSent = false;
                return;
            
            case SESSION_CREATED:
                profileSessionCreated = false;
                return;
            
            case SESSION_OPENED:
                profileSessionOpened = false;
                return;
            
            case SESSION_IDLE:
                profileSessionIdle = false;
                return;
            
            case SESSION_CLOSED:
                profileSessionClosed = false;
                return;
            
            default:
                return;
        }
    }

    /**
     * Return the set of {@link IoEventType} which are profiled.
     *
     * @return a Set containing all the profiled {@link IoEventType}
     */
    public Set<IoEventType> getEventsToProfile() {
        Set<IoEventType> set = new HashSet<>();
        
        if (profileMessageReceived) {
            set.add(IoEventType.MESSAGE_RECEIVED);
        }
        
        if (profileMessageSent) {
            set.add(IoEventType.MESSAGE_SENT);
        }
        
        if (profileSessionCreated) {
            set.add(IoEventType.SESSION_CREATED);
        }
        
        if (profileSessionOpened) {
            set.add(IoEventType.SESSION_OPENED);
        }
        
        if (profileSessionIdle) {
            set.add(IoEventType.SESSION_IDLE);
        }
        
        if (profileSessionClosed) {
            set.add(IoEventType.SESSION_CLOSED);
        }
        
        return set;
    }

    /**
     * Set the profilers for a list of {@link IoEventType}
     * 
     * @param eventTypes
     *            the list of {@link IoEventType} to profile
     */
    public void setEventsToProfile(IoEventType... eventTypes) {
        setProfilers(eventTypes);
    }

    /**
     * Profile a MessageReceived event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     * @param message
     *            the received message
     */
    @Override
    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
        if (profileMessageReceived) {
            long start = timeNow();
            nextFilter.messageReceived(session, message);
            long end = timeNow();
            messageReceivedTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.messageReceived(session, message);
        }
    }

    /**
     * Profile a MessageSent event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     * @param writeRequest
     *            the sent message
     */
    @Override
    public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
        if (profileMessageSent) {
            long start = timeNow();
            nextFilter.messageSent(session, writeRequest);
            long end = timeNow();
            messageSentTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.messageSent(session, writeRequest);
        }
    }

    /**
     * Profile a SessionCreated event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     */
    @Override
    public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception {
        if (profileSessionCreated) {
            long start = timeNow();
            nextFilter.sessionCreated(session);
            long end = timeNow();
            sessionCreatedTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.sessionCreated(session);
        }
    }

    /**
     * Profile a SessionOpened event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     */
    @Override
    public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
        if (profileSessionOpened) {
            long start = timeNow();
            nextFilter.sessionOpened(session);
            long end = timeNow();
            sessionOpenedTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.sessionOpened(session);
        }
    }

    /**
     * Profile a SessionIdle event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     * @param status
     *            The session's status
     */
    @Override
    public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
        if (profileSessionIdle) {
            long start = timeNow();
            nextFilter.sessionIdle(session, status);
            long end = timeNow();
            sessionIdleTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.sessionIdle(session, status);
        }
    }

    /**
     * Profile a SessionClosed event. This method will gather the following informations : - the method duration - the
     * shortest execution time - the slowest execution time - the average execution time - the global number of calls
     * 
     * @param nextFilter
     *            The filter to call next
     * @param session
     *            The associated session
     */
    @Override
    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
        if (profileSessionClosed) {
            long start = timeNow();
            nextFilter.sessionClosed(session);
            long end = timeNow();
            sessionClosedTimerWorker.addNewDuration(end - start);
        } else {
            nextFilter.sessionClosed(session);
        }
    }

    /**
     * Get the average time for the specified method represented by the {@link IoEventType}
     *
     * @param type
     *            The {@link IoEventType} that the user wants to get the average method call time
     * @return The average time it took to execute the method represented by the {@link IoEventType}
     */
    public double getAverageTime(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                if (profileMessageReceived) {
                    return messageReceivedTimerWorker.getAverage();
                }
            
                break;
            
            case MESSAGE_SENT:
                if (profileMessageSent) {
                    return messageSentTimerWorker.getAverage();
                }
            
                break;
            
            case SESSION_CREATED:
                if (profileSessionCreated) {
                    return sessionCreatedTimerWorker.getAverage();
                }
            
                break;
            
            case SESSION_OPENED:
                if (profileSessionOpened) {
                    return sessionOpenedTimerWorker.getAverage();
                }
            
                break;
            
            case SESSION_IDLE:
                if (profileSessionIdle) {
                    return sessionIdleTimerWorker.getAverage();
                }
            
                break;
            
            case SESSION_CLOSED:
                if (profileSessionClosed) {
                    return sessionClosedTimerWorker.getAverage();
                }
            
                break;
            
            default:
                break;
        }
        
        throw new IllegalArgumentException("You are not monitoring this event.  Please add this event first.");
    }

    /**
     * Gets the total number of times the method has been called that is represented by the {@link IoEventType}
     *
     * @param type
     *            The {@link IoEventType} that the user wants to get the total number of method calls
     * @return The total number of method calls for the method represented by the {@link IoEventType}
     */
    public long getTotalCalls(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                if (profileMessageReceived) {
                    return messageReceivedTimerWorker.getCallsNumber();
                }
            
                break;
            
            case MESSAGE_SENT:
                if (profileMessageSent) {
                    return messageSentTimerWorker.getCallsNumber();
                }
            
                break;
            
            case SESSION_CREATED:
                if (profileSessionCreated) {
                    return sessionCreatedTimerWorker.getCallsNumber();
                }
            
                break;
            
            case SESSION_OPENED:
                if (profileSessionOpened) {
                    return sessionOpenedTimerWorker.getCallsNumber();
                }
            
                break;
            
            case SESSION_IDLE:
                if (profileSessionIdle) {
                    return sessionIdleTimerWorker.getCallsNumber();
                }
            
                break;
            
            case SESSION_CLOSED:
                if (profileSessionClosed) {
                    return sessionClosedTimerWorker.getCallsNumber();
                }
            
                break;
            
            default:
                break;
        }
        
        throw new IllegalArgumentException("You are not monitoring this event.  Please add this event first.");
    }

    /**
     * The total time this method has been executing
     *
     * @param type
     *            The {@link IoEventType} that the user wants to get the total time this method has been executing
     * @return The total time for the method represented by the {@link IoEventType}
     */
    public long getTotalTime(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                if (profileMessageReceived) {
                    return messageReceivedTimerWorker.getTotal();
                }
            
                break;
            
            case MESSAGE_SENT:
                if (profileMessageSent) {
                    return messageSentTimerWorker.getTotal();
                }
            
                break;
            
            case SESSION_CREATED:
                if (profileSessionCreated) {
                    return sessionCreatedTimerWorker.getTotal();
                }
            
                break;
            
            case SESSION_OPENED:
                if (profileSessionOpened) {
                    return sessionOpenedTimerWorker.getTotal();
                }
            
                break;
            
            case SESSION_IDLE:
                if (profileSessionIdle) {
                    return sessionIdleTimerWorker.getTotal();
                }
            
                break;
            
            case SESSION_CLOSED:
                if (profileSessionClosed) {
                    return sessionClosedTimerWorker.getTotal();
                }
            
                break;
            
            default:
                break;
        }
        
        throw new IllegalArgumentException("You are not monitoring this event.  Please add this event first.");
    }

    /**
     * The minimum time the method represented by {@link IoEventType} has executed
     *
     * @param type
     *            The {@link IoEventType} that the user wants to get the minimum time this method has executed
     * @return The minimum time this method has executed represented by the {@link IoEventType}
     */
    public long getMinimumTime(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                if (profileMessageReceived) {
                    return messageReceivedTimerWorker.getMinimum();
                }
            
                break;
            
            case MESSAGE_SENT:
                if (profileMessageSent) {
                    return messageSentTimerWorker.getMinimum();
                }
            
                break;
            
            case SESSION_CREATED:
                if (profileSessionCreated) {
                    return sessionCreatedTimerWorker.getMinimum();
                }
            
                break;
            
            case SESSION_OPENED:
                if (profileSessionOpened) {
                    return sessionOpenedTimerWorker.getMinimum();
                }
            
                break;
            
            case SESSION_IDLE:
                if (profileSessionIdle) {
                    return sessionIdleTimerWorker.getMinimum();
                }
            
                break;
            
            case SESSION_CLOSED:
                if (profileSessionClosed) {
                    return sessionClosedTimerWorker.getMinimum();
                }
            
                break;
            
            default:
                break;
        }
        
        throw new IllegalArgumentException("You are not monitoring this event.  Please add this event first.");
    }

    /**
     * The maximum time the method represented by {@link IoEventType} has executed
     *
     * @param type
     *            The {@link IoEventType} that the user wants to get the maximum time this method has executed
     * @return The maximum time this method has executed represented by the {@link IoEventType}
     */
    public long getMaximumTime(IoEventType type) {
        switch (type) {
            case MESSAGE_RECEIVED:
                if (profileMessageReceived) {
                    return messageReceivedTimerWorker.getMaximum();
                }
            
                break;
            
            case MESSAGE_SENT:
                if (profileMessageSent) {
                    return messageSentTimerWorker.getMaximum();
                }
            
                break;
            
            case SESSION_CREATED:
                if (profileSessionCreated) {
                    return sessionCreatedTimerWorker.getMaximum();
                }
            
                break;
            
            case SESSION_OPENED:
                if (profileSessionOpened) {
                    return sessionOpenedTimerWorker.getMaximum();
                }
            
                break;
            
            case SESSION_IDLE:
                if (profileSessionIdle) {
                    return sessionIdleTimerWorker.getMaximum();
                }
            
                break;
            
            case SESSION_CLOSED:
                if (profileSessionClosed) {
                    return sessionClosedTimerWorker.getMaximum();
                }
            
                break;
            
            default:
                break;
        }
        
        throw new IllegalArgumentException("You are not monitoring this event.  Please add this event first.");
    }

    /**
     * Class that will track the time each method takes and be able to provide information for each method.
     *
     */
    private class TimerWorker {
        /** The sum of all operation durations */
        private final AtomicLong total;
        
        /** The number of calls */
        private final AtomicLong callsNumber;
        
        /** The fastest operation */
        private final AtomicLong minimum;
        
        /** The slowest operation */
        private final AtomicLong maximum;
        
        /** A lock for synchinized blocks */
        private final Object lock = new Object();
        
        /**
         * Creates a new instance of TimerWorker.
         *
         */
        public TimerWorker() {
            total = new AtomicLong();
            callsNumber = new AtomicLong();
            minimum = new AtomicLong();
            maximum = new AtomicLong();
        }
        
        /**
         * Add a new operation duration to this class. Total is updated and calls is incremented
         *
         * @param duration
         *            The new operation duration
         */
        public void addNewDuration(long duration) {
            callsNumber.incrementAndGet();
            total.addAndGet(duration);
        
            synchronized (lock) {
                // this is not entirely thread-safe, must lock
                if (duration < minimum.longValue()) {
                    minimum.set(duration);
                }
            
                // this is not entirely thread-safe, must lock
                if (duration > maximum.longValue()) {
                    maximum.set(duration);
                }
            }
        }
        
        /**
         * Gets the average reading for this event
         *
         * @return the average reading for this event
         */
        public double getAverage() {
            synchronized (lock) {
                // There are two operations, we need to synchronize the block
                return callsNumber.longValue() != 0 ? total.longValue() / callsNumber.longValue() : 0;
            }
        }
        
        /**
         * @return The total number of profiled operation
         */
        public long getCallsNumber() {
            return callsNumber.longValue();
        }
        
        /**
         * @return the total time
         */
        public long getTotal() {
            return total.longValue();
        }
        
        /**
         * @return the lowest execution time
         */
        public long getMinimum() {
            return minimum.longValue();
        }
        
        /**
         * @return the longest execution time
         */
        public long getMaximum() {
            return maximum.longValue();
        }
    }

    /**
     * @return the current time, expressed using the fixed TimeUnit.
     */
    private long timeNow() {
        switch (timeUnit) {
            case SECONDS:
                return System.currentTimeMillis() / 1000;
            
            case MICROSECONDS:
                return System.nanoTime() / 1000;
            
            case NANOSECONDS:
                return System.nanoTime();
            
            default:
                return System.currentTimeMillis();
        }
    }
}
