package org.apache.catalina.tribes.test.channel;

import junit.framework.TestCase;
import java.io.Serializable;
import java.util.Random;
import java.util.Arrays;
import org.apache.catalina.tribes.ChannelListener;
import org.apache.catalina.tribes.Member;
import org.apache.catalina.tribes.group.GroupChannel;
import java.io.PrintStream;

/**
 * <p>Title: </p> 
 * 
 * <p>Description: </p> 
 * 
 * <p>Copyright: Copyright (c) 2005</p> 
 * 
 * <p>Company: </p>
 * 
 * @author not attributable
 * @version 1.0
 */
public class TestRemoteProcessException extends TestCase {
    int msgCount = 10000;
    GroupChannel channel1;
    GroupChannel channel2;
    Listener listener1;
    protected void setUp() throws Exception {
        super.setUp();
        channel1 = new GroupChannel();
        channel2 = new GroupChannel();
        listener1 = new Listener();
        channel2.addChannelListener(listener1);
        channel1.start(GroupChannel.DEFAULT);
        channel2.start(GroupChannel.DEFAULT);
    }

    protected void tearDown() throws Exception {
        super.tearDown();
        channel1.stop(GroupChannel.DEFAULT);
        channel2.stop(GroupChannel.DEFAULT);
    }

    public void testDataSendSYNCACK() throws Exception {
        System.err.println("Starting SYNC_ACK");
        int errC=0, nerrC=0;
        for (int i=0; i<msgCount; i++) {
            boolean error = Data.r.nextBoolean();
            channel1.send(channel1.getMembers(),Data.createRandomData(error),GroupChannel.SEND_OPTIONS_SYNCHRONIZED_ACK|GroupChannel.SEND_OPTIONS_USE_ACK);
            if ( error ) errC++; else nerrC++;
        }
        System.err.println("Finished SYNC_ACK");
        assertEquals("Checking failure messages.",errC,listener1.errCnt);
        assertEquals("Checking success messages.",nerrC,listener1.noErrCnt);
        assertEquals("Checking all messages.",msgCount,listener1.noErrCnt+listener1.errCnt);
        System.out.println("Listener 1 stats:");
        listener1.printStats(System.out);
    }

    public static class Listener implements ChannelListener {
        long noErrCnt = 0;
        long errCnt = 0;
        public boolean accept(Serializable s, Member m) {
            return (s instanceof Data);
        }

        public void messageReceived(Serializable s, Member m) {
            Data d = (Data)s;
            if ( !Data.verify(d) ) {
                System.err.println("ERROR");
            } else {
                if (d.error) {
                    errCnt++;
                    if ( (errCnt % 100) == 0) {
                        printStats(System.err);
                    }
                    throw new IllegalArgumentException();
                } else {
                    noErrCnt++;
                    if ( (noErrCnt % 100) == 0) {
                        printStats(System.err);
                    }
                }
            }
        }

        public void printStats(PrintStream stream) {
            stream.println("NORMAL:" + noErrCnt);
            stream.println("FAILURES:" + errCnt);
            stream.println("TOTAL:" + (errCnt+noErrCnt));
        }
    }

    public static class Data implements Serializable {
        public int length;
        public byte[] data;
        public byte key;
        public boolean error = false;
        public static Random r = new Random(System.currentTimeMillis());
        public static Data createRandomData(boolean error) {
            int i = r.nextInt();
            i = ( i % 127 );
            int length = Math.abs(r.nextInt() % 65555);
            Data d = new Data();
            d.length = length;
            d.key = (byte)i;
            d.data = new byte[length];
            Arrays.fill(d.data,d.key);
            d.error = error;
            return d;
        }

        public static boolean verify(Data d) {
            boolean result = (d.length == d.data.length);
            for ( int i=0; result && (i<d.data.length); i++ ) result = result && d.data[i] == d.key;
            return result;
        }
    }



}
