package edu.cmu.cs.diamond.opendiamond;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

class Connection {

    private static final int DIAMOND_PORT = 5872;

    private static final int NONCE_SIZE = 16;

    final private MiniRPCConnection controlSocket;

    final private MiniRPCConnection dataSocket;

    final private String hostname;

    public String getHostname() {
        return hostname;
    }

    private static SocketChannel createOneConnection(InetSocketAddress address,
            byte nonce[]) throws IOException {
        if (nonce.length != NONCE_SIZE) {
            throw new IllegalArgumentException("nonce[] must be NONCE_SIZE ("
                    + NONCE_SIZE + "), actual size " + nonce.length);
        }

        SocketChannel sc = SocketChannel.open(address);

        ByteBuffer buf = ByteBuffer.wrap(nonce);

        int size;

        // write nonce
        // System.out.println("writing " + Arrays.toString(nonce));
        size = sc.write(buf);
        if (size != NONCE_SIZE) {
            throw new IOException("Could not write nonce, size: " + size);
        }
        // read nonce
        buf.clear();

        size = sc.read(buf);
        if (size != NONCE_SIZE) {
            throw new IOException("Could not read nonce, size: " + size);
        }
        // System.out.println("read " + Arrays.toString(nonce));

        return sc;
    }

    public Connection(String host) throws IOException {
        byte nonce[] = new byte[NONCE_SIZE];

        this.hostname = host;

        // open control
        controlSocket = new MiniRPCConnection(createOneConnection(
                new InetSocketAddress(host, DIAMOND_PORT), nonce));

        // open data
        dataSocket = new MiniRPCConnection(createOneConnection(
                new InetSocketAddress(host, DIAMOND_PORT), nonce));
    }

    public void close() {
        try {
            controlSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            dataSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            ConnectionAggregate ca = new ConnectionAggregate();

            for (String s : args) {
                ca.add(new Connection(s));
            }

            // send some messages
            requestCharactistics(ca);
            requestCharactistics(ca);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    private static void requestCharactistics(ConnectionAggregate ca)
            throws InterruptedException, ExecutionException {
        CompletionService<MiniRPCReply> cs = ca.sendToAllControlChannels(
                MiniRPCMessage.MINIRPC_PENDING, 14, new byte[0]);
        for (int i = 0; i < ca.size(); i++) {
            Future<MiniRPCReply> f = cs.take();
            MiniRPCReply mrr = f.get();
            System.out.println(mrr.getHostname() + ": "
                    + new XDR_dev_char(mrr.getMessage().getData()));
        }
    }

    MiniRPCConnection getControlConnection() {
        return controlSocket;
    }

    MiniRPCConnection getDataConnection() {
        return dataSocket;
    }
}

@@ -168,139 +168,8 @@
 nel;
-%0Aimport java.util.concurrent.CompletionService;%0Aimport java.util.concurrent.ExecutionException;%0Aimport java.util.concurrent.Future;
 %0A%0Acl
@@ -2203,1117 +2203,8 @@
  %7D%0A%0A
-    public static void main(String%5B%5D args) %7B%0A        try %7B%0A            ConnectionAggregate ca = new ConnectionAggregate();%0A%0A            for (String s : args) %7B%0A                ca.add(new Connection(s));%0A            %7D%0A%0A            // send some messages%0A            requestCharactistics(ca);%0A            requestCharactistics(ca);%0A        %7D catch (IOException e) %7B%0A            e.printStackTrace();%0A        %7D catch (InterruptedException e) %7B%0A            e.printStackTrace();%0A        %7D catch (ExecutionException e) %7B%0A            e.printStackTrace();%0A        %7D%0A    %7D%0A%0A    private static void requestCharactistics(ConnectionAggregate ca)%0A            throws InterruptedException, ExecutionException %7B%0A        CompletionService%3CMiniRPCReply%3E cs = ca.sendToAllControlChannels(%0A                MiniRPCMessage.MINIRPC_PENDING, 14, new byte%5B0%5D);%0A        for (int i = 0; i %3C ca.size(); i++) %7B%0A            Future%3CMiniRPCReply%3E f = cs.take();%0A            MiniRPCReply mrr = f.get();%0A            System.out.println(mrr.getHostname() + %22: %22%0A                    + new XDR_dev_char(mrr.getMessage().getData()));%0A        %7D%0A    %7D%0A%0A
     

Remove main from Connection