ListCommand: Show queue details for destinations

When the --detail option is given, show the current queue
(pending and in-flight) per destination.

Change-Id: I0683b82f0eac4ca872946889ae5f4ccf1837e604
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
index 1090fb6..d93bf51 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -16,6 +16,7 @@
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.collect.Lists;
@@ -98,6 +99,17 @@
     TRANSPORT_ERROR, COLLISION, REPOSITORY_MISSING;
   }
 
+  public static class QueueInfo {
+    public final Map<URIish, PushOne> pending;
+    public final Map<URIish, PushOne> inFlight;
+
+    public QueueInfo(Map<URIish, PushOne> pending,
+        Map<URIish, PushOne> inFlight) {
+      this.pending = ImmutableMap.copyOf(pending);
+      this.inFlight = ImmutableMap.copyOf(inFlight);
+    }
+  }
+
   protected Destination(final Injector injector,
       final RemoteConfig rc,
       final Config cfg,
@@ -203,6 +215,12 @@
     }
   }
 
+  public QueueInfo getQueueInfo() {
+    synchronized (stateLock) {
+      return new QueueInfo(pending, inFlight);
+    }
+  }
+
   public void start(WorkQueue workQueue) {
     pool = workQueue.createQueue(poolThreads, poolName);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
index 030e5ec..d0ac12c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ListCommand.java
@@ -28,6 +28,8 @@
 
 import org.kohsuke.args4j.Option;
 
+import java.util.Collection;
+
 @RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
 @CommandMetaData(name = "list", description = "List remote destination information")
 final class ListCommand extends SshCommand {
@@ -68,6 +70,25 @@
     }
   }
 
+  private void addQueueDetails(StringBuilder out, Collection<PushOne> values) {
+    for (PushOne p : values) {
+      out.append("  ")
+        .append(p.toString())
+        .append("\n");
+    }
+  }
+
+  private void addQueueDetails(JsonObject obj, String key,
+      Collection<PushOne> values) {
+    if (values.size() > 0) {
+      JsonArray list = new JsonArray();
+      for (PushOne p : values) {
+        list.add(new JsonPrimitive(p.toString()));
+      }
+      obj.add(key, list);
+    }
+  }
+
   private void printRemote(Destination d) {
     if (json) {
       JsonObject obj = new JsonObject();
@@ -77,6 +98,9 @@
         addProperty(obj, "AdminUrl", d.getAdminUrls());
         addProperty(obj, "AuthGroup", d.getAuthGroupNames());
         addProperty(obj, "Project", d.getProjects());
+        Destination.QueueInfo q = d.getQueueInfo();
+        addQueueDetails(obj, "InFlight", q.inFlight.values());
+        addQueueDetails(obj, "Pending", q.pending.values());
       }
       stdout.print(obj.toString() + "\n");
     } else {
@@ -108,6 +132,16 @@
             .append(project)
             .append("\n");
         }
+
+        Destination.QueueInfo q = d.getQueueInfo();
+        out.append("In Flight: ")
+          .append(q.inFlight.size())
+          .append("\n");
+        addQueueDetails(out, q.inFlight.values());
+        out.append("Pending: ")
+          .append(q.pending.size())
+          .append("\n");
+        addQueueDetails(out, q.pending.values());
       }
       stdout.print(out.toString() + "\n");
     }
diff --git a/src/main/resources/Documentation/cmd-list.md b/src/main/resources/Documentation/cmd-list.md
index 9cc28a2..3c6b78f 100644
--- a/src/main/resources/Documentation/cmd-list.md
+++ b/src/main/resources/Documentation/cmd-list.md
@@ -34,7 +34,8 @@
 	the `PATTERN`.
 
 `--detail`
-:	Print additional detailed information: AdminUrl, AuthGroup and Project.
+:	Print additional detailed information: AdminUrl, AuthGroup, Project
+	and queue (pending and in-flight).
 
 `--json`
 :	Output in json format.