package anastore.net.test;

import anastore.net.*;
import anastore.util.*;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Simple test of the channel system. This models the traffic pattern
 * seen by our block store: the client periodically sends synchronous
 * query messages, to which the server responds with a reply
 * message. Also, the server periodically sends invalidation
 * messages. Of course, in the test, these messages have no meaning
 * and no payload other than an integer id.
 *
 * The client connects to the server on the specified host and
 * port. It starts a timer thread that sends query messages on the
 * root send channel every five seconds and waits for the replies. The
 * main thread reads the root receive channel for invalidation
 * messages and promptly ignores them.
 *
 * Prints a message to stdout every time a message is sent or
 * received.
 */
public class TestClient {

    private static ChannelClient client;
    private static SendChannel send;
    private static ReceiveChannel recv;
    private static int lastQuery = 0;
    

    /**
     * Start running the test. The first argument is the host to
     * onnect to, and the second argument is the port. Should not
     * terminate.
     */
    public static final void main(final String[] args)
        throws IOException, InterruptedException {
        client = new ChannelClient(args[0],
                                   Integer.parseInt(args[1]));

        // Make the connection
        Pair<SendChannel, ReceiveChannel> channels =
            client.connect();
        send = channels.first;
        recv = channels.second;

        /*
         * Start a timer to send query messages and wait for the
         * responses.
         */
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    lastQuery += 1;
                    QueryMessage qmsg = new QueryMessage(lastQuery);
                    ReceiveChannel response;
                    System.out.println("Sending query message " +
                                       qmsg.payload);
                    try {
                        response = send.send(qmsg);
                        Pair<Message, SendChannel> received = response.receive();
                        ResponseMessage rmsg =
                            (ResponseMessage) received.first;
                        System.out.println("Received response message " +
                                           rmsg.payload);
                    } catch (IOException e) {
                        System.out.println("IOException: " + e.toString());
                    } catch (InterruptedException e) {
                        System.out.println("InterruptedException: " +
                                           e.toString());
                    }
                }
            }, 0, 500);

        /*
         * In the main thread, loop forever, receiving invalidation
         * messages and printing them.
         */
        while (true) {
            InvalidationMessage imsg;
            try {
                Pair<Message, SendChannel> received = recv.receive();
                imsg = (InvalidationMessage) received.first;
                System.out.println("Received invalidation message " +
                                   imsg.payload);
            } catch (IOException e) {
                System.out.println("IOException: " + e.toString());
            } catch (InterruptedException e) {
                System.out.println("InterruptedException: " + e.toString());
            }
        }
    }
}
