/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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
 */

package org.apache.catalina.tribes.group.interceptors;

import org.apache.catalina.tribes.ChannelException;
import org.apache.catalina.tribes.ChannelMessage;
import org.apache.catalina.tribes.Member;
import org.apache.catalina.tribes.group.ChannelInterceptorBase;
import org.apache.catalina.tribes.group.InterceptorPayload;
import org.apache.catalina.tribes.io.ChannelData;
import org.apache.catalina.tribes.io.XByteBuffer;
import java.text.DecimalFormat;
import org.apache.catalina.tribes.membership.MemberImpl;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;



/**
 *
 *
 * @author Filip Hanik
 * @version 1.0
 */
public class ThroughputInterceptor extends ChannelInterceptorBase {
    protected static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(ThroughputInterceptor.class);

    double mbTx = 0;
    double mbAppTx = 0;
    double mbRx = 0;
    double timeTx = 0;
    double lastCnt = 0;
    AtomicLong msgTxCnt = new AtomicLong(1);
    AtomicLong msgRxCnt = new AtomicLong(0);
    AtomicLong msgTxErr = new AtomicLong(0);
    int interval = 10000;
    AtomicInteger access = new AtomicInteger(0);
    long txStart = 0;
    long rxStart = 0;
    DecimalFormat df = new DecimalFormat("#0.00");


    public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException {
        if ( access.addAndGet(1) == 1 ) txStart = System.currentTimeMillis();
        long bytes = XByteBuffer.getDataPackageLength(((ChannelData)msg).getDataPackageLength());
        try {
            super.sendMessage(destination, msg, payload);
        }catch ( ChannelException x ) {
            msgTxErr.addAndGet(1);
            access.addAndGet(-1);
            throw x;
        } 
        mbTx += ((double)(bytes*destination.length))/(1024d*1024d);
        mbAppTx += ((double)(bytes))/(1024d*1024d);
        if ( access.addAndGet(-1) == 0 ) {
            long stop = System.currentTimeMillis();
            timeTx += ( (double) (stop - txStart)) / 1000d;
            if ((msgTxCnt.get() / interval) >= lastCnt) {
                lastCnt++;
                report(timeTx);
            }
        }
        msgTxCnt.addAndGet(1);
    }

    public void messageReceived(ChannelMessage msg) {
        if ( rxStart == 0 ) rxStart = System.currentTimeMillis();
        long bytes = XByteBuffer.getDataPackageLength(((ChannelData)msg).getDataPackageLength());
        mbRx += ((double)bytes)/(1024d*1024d);
        msgRxCnt.addAndGet(1);
        if ( msgRxCnt.get() % interval == 0 ) report(timeTx);
        super.messageReceived(msg);
        
    }
    
    public void report(double timeTx) {
        StringBuffer buf = new StringBuffer("ThroughputInterceptor Report[\n\tTx Msg:");
        buf.append(msgTxCnt).append(" messages\n\tSent:");
        buf.append(df.format(mbTx));
        buf.append(" MB (total)\n\tSent:");
        buf.append(df.format(mbAppTx));
        buf.append(" MB (application)\n\tTime:");
        buf.append(df.format(timeTx));
        buf.append(" seconds\n\tTx Speed:");
        buf.append(df.format(mbTx/timeTx));
        buf.append(" MB/sec (total)\n\tTxSpeed:");
        buf.append(df.format(mbAppTx/timeTx));
        buf.append(" MB/sec (application)\n\tError Msg:");
        buf.append(msgTxErr).append("\n\tRx Msg:");
        buf.append(msgRxCnt);
        buf.append(" messages\n\tRx Speed:");
        buf.append(df.format(mbRx/((double)((System.currentTimeMillis()-rxStart)/1000))));
        buf.append(" MB/sec (since 1st msg)\n\tReceived:");
        buf.append(df.format(mbRx)).append(" MB]\n");
        if ( log.isInfoEnabled() ) log.info(buf);
    }
    
    public void setInterval(int interval) {
        this.interval = interval;
    }

    public int getInterval() {
        return interval;
    }

}
