package com.orbekk.same;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.RpcCallback;
import com.orbekk.protobuf.NewRpcChannel;
import com.orbekk.protobuf.Rpc;
import com.orbekk.protobuf.RpcChannel;
import com.orbekk.same.Services.NetworkDirectory;

public class DirectoryApp {
    private static final Logger logger =
            LoggerFactory.getLogger(DirectoryApp.class);
    public static final int CONNECTION_TIMEOUT = 2 * 1000;
    public static final int READ_TIMEOUT = 2 * 1000;
    private String[] args;
    
    public DirectoryApp(String[] args) {
        this.args = args;
    }
    
    public void run() {
        String host = args[0];
        int port = Integer.valueOf(args[1]);
        NewRpcChannel channel = null;
        try {
            channel = NewRpcChannel.create(host, port);
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
            System.exit(1);
        } catch (IOException e1) {
            e1.printStackTrace();
            System.exit(1);
        }
        Services.Directory directory = Services.Directory.newStub(channel);

        final CountDownLatch finished = new CountDownLatch(1);
        final Rpc rpc = new Rpc();
        RpcCallback<NetworkDirectory> callback =
                new RpcCallback<NetworkDirectory>() {
            @Override public void run(NetworkDirectory directory) {
                if (rpc.failed()) {
                    System.err.println("Failed to get network list.");
                } else {
                    System.out.println("Networks:");
                    for (Services.MasterState network :
                        directory.getNetworkList()) {
                        System.out.println(network.getNetworkName() + "\t" +
                                network.getMasterUrl());
                    }
                }
                finished.countDown();
            }
        };
        directory.getNetworks(rpc, Services.Empty.getDefaultInstance(),
                callback);
        try {
            finished.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("Closing channel.");
        channel.close();
    }
    
    public static void main(String[] args) {
        new DirectoryApp(args).run();
    }
}

@@ -333,32 +333,159 @@
 buf.RpcChannel;%0A
+import com.orbekk.same.Services.Directory;%0Aimport com.orbekk.same.Services.Empty;%0Aimport com.orbekk.same.Services.MasterState;%0A
 import com.orbek
@@ -876,140 +876,272 @@
    p
-ublic void run() %7B%0A        String host = args%5B0%5D;%0A        int port = Integer.valueOf(args%5B1%5D);%0A        NewRpcChannel channel = null;
+rivate void addTestNetwork(Directory directory) throws InterruptedException %7B%0A        final Rpc rpc = new Rpc();%0A        MasterState request = MasterState.newBuilder()%0A                .setNetworkName(%22Test network%22)%0A                .setMasterUrl(%22invalid:invalid%22)
 %0A   
@@ -1141,38 +1141,32 @@
 d%22)%0A        
-try %7B%0A
         
     channel 
@@ -1157,256 +1157,307 @@
     
-    chan
+.build();%0A        RpcCallback%3CEmpty%3E do
 ne
-l
  = 
-N
+n
 ew
+ 
 RpcC
-hannel.create(host, port);%0A        %7D catch (UnknownHostException e1) %7B%0A            e1.printStackTrace();%0A            System.exit(1);%0A        %7D catch (IOException e1) %7B%0A            e1.printStackTrace();%0A            System.exit(1
+allback%3CEmpty%3E() %7B%0A            @Override public void run(Empty unused) %7B%0A            %7D%0A        %7D;%0A        directory.registerNetwork(rpc, request, done);%0A        rpc.await();%0A        if (rpc.isOk()) %7B%0A            System.out.println(%22Added network.%22
 );%0A 
@@ -1473,143 +1473,95 @@
     
+%7D%0A
     
-Services.Directory directory = Services.Directory.newStub(channel);%0A%0A        final CountDownLatch finished = new CountDownLatch(1);
+%0A    private void listNetworks(Directory directory) throws InterruptedException %7B
 %0A   
@@ -1630,24 +1630,20 @@
 ectory%3E 
-callback
+done
  =%0A     
@@ -2232,46 +2232,8 @@
   %7D%0A
-                finished.countDown();%0A
     
@@ -2288,25 +2288,16 @@
 ks(rpc, 
-Services.
 Empty.ge
@@ -2315,16 +2315,23 @@
 tance(),
+ done);
 %0A       
@@ -2335,68 +2335,265 @@
     
-        callback);%0A        try %7B%0A            finished.await(
+rpc.await();%0A    %7D%0A    %0A    public void run() throws InterruptedException %7B%0A        String host = args%5B0%5D;%0A        int port = Integer.valueOf(args%5B1%5D);%0A        NewRpcChannel channel = null;%0A        try %7B%0A            channel = NewRpcChannel.create(host, port
 );%0A 
@@ -2608,27 +2608,27 @@
  catch (
-Interrupted
+UnknownHost
 Exceptio
@@ -2630,16 +2630,17 @@
 eption e
+1
 ) %7B%0A    
@@ -2648,16 +2648,17 @@
        e
+1
 .printSt
@@ -2681,64 +2681,276 @@
     
-%7D%0A        %0A        System.out.println(%22Closing channel.%22
+    System.exit(1);%0A        %7D catch (IOException e1) %7B%0A            e1.printStackTrace();%0A            System.exit(1);%0A        %7D%0A        Services.Directory directory = Services.Directory.newStub(channel);%0A        addTestNetwork(directory);%0A        listNetworks(directory
 );%0A 
@@ -3021,32 +3021,50 @@
 tring%5B%5D args) %7B%0A
+        try %7B%0A    
         new Dire
@@ -3081,20 +3081,141 @@
 rgs).run();%0A
+        %7D catch (InterruptedException e) %7B%0A            throw new AssertionError(%22Should not be interrupted.%22);%0A        %7D%0A
     %7D%0A%7D%0A

Use Rpc.await() functionality.