Merge "Add sort and filter options to REST endpoint"
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsDropDownPanel.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsDropDownPanel.java
index d89ee82..23017f0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsDropDownPanel.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsDropDownPanel.java
@@ -48,7 +48,8 @@
         panel.getObject(GerritUiExtensionPoint.Key.REVISION_INFO).cast();
     new RestApi("changes").id(change.id()).view("revisions").id(rev.id())
         .view(Plugin.get().getPluginName(), "verifications")
-        .addParameter("current", true)
+        .addParameter("sort", "REPORTER")
+        .addParameter("filter", "CURRENT")
         .get(new AsyncCallback<NativeMap<VerificationInfo>>() {
           @Override
           public void onSuccess(NativeMap<VerificationInfo> result) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
index c5d7286..ecc0dc0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/JobsPanel.java
@@ -47,7 +47,8 @@
         panel.getObject(GerritUiExtensionPoint.Key.REVISION_INFO).cast();
     new RestApi("changes").id(change.id()).view("revisions").id(rev.id())
         .view(Plugin.get().getPluginName(), "verifications")
-        .addParameter("current", true)
+        .addParameter("sort", "REPORTER")
+        .addParameter("filter", "CURRENT")
         .get(new AsyncCallback<NativeMap<VerificationInfo>>() {
           @Override
           public void onSuccess(NativeMap<VerificationInfo> result) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetVerifications.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetVerifications.java
index 583577c..e900a3a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetVerifications.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/GetVerifications.java
@@ -31,7 +31,6 @@
 import java.sql.Timestamp;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -43,9 +42,20 @@
     this.schemaFactory = schemaFactory;
   }
 
-  @Option(name = "--current", aliases = {"-c"},
-      usage = "List only the current report")
-  private boolean current;
+  private String sort;
+  private String filter;
+
+  @Option(name = "--sort", aliases = {"-s"}, metaVar = "SORT",
+      usage = "Sort the list by an entry")
+  public void setSort(String sort) {
+    this.sort = sort.toUpperCase();
+  }
+
+  @Option(name = "--filter", aliases = {"-f"}, metaVar = "FILTER",
+      usage = "filter the results")
+  public void setFilter(String filter) {
+    this.filter = filter.toUpperCase();
+  }
 
   @Override
   public Map<String, VerificationInfo> apply(RevisionResource rsrc)
@@ -55,40 +65,73 @@
       ResultSet<PatchSetVerification> rs =
           db.patchSetVerifications().byPatchSet(rsrc.getPatchSet().getId());
       List<PatchSetVerification> jobs = rs.toList();
-      // sort the jobs list by reporter (acending) then reported date (decending)
-      Collections.sort(jobs, new Comparator<PatchSetVerification>() {
-        @Override
-        public int compare(PatchSetVerification a, PatchSetVerification b) {
-          return new CompareToBuilder()
-              .append(a.getReporter(),b.getReporter())
-              .append(b.getGranted(),a.getGranted())
-              .toComparison();
+      if (sort != null && !sort.isEmpty()) {
+        // sort the jobs list by reporter (ascending) then reported date (descending)
+        if (sort.equals("REPORTER")) {
+          Collections.sort(jobs, new Comparator<PatchSetVerification>() {
+            @Override
+            public int compare(PatchSetVerification a, PatchSetVerification b) {
+              return new CompareToBuilder()
+                  .append(a.getReporter(),b.getReporter())
+                  .append(b.getGranted(),a.getGranted())
+                  .toComparison();
+            }
+          });
+        } else if (sort.equals("NAME")) {
+          // sort the jobs list by name (ascending) then reported date (descending)
+          Collections.sort(jobs, new Comparator<PatchSetVerification>() {
+            @Override
+            public int compare(PatchSetVerification a, PatchSetVerification b) {
+              return new CompareToBuilder()
+                  .append(a.getName(),b.getName())
+                  .append(b.getGranted(),a.getGranted())
+                  .toComparison();
+            }
+          });
         }
-      });
+      }
 
-      if (current) {
-        Map<String, Timestamp> reported = new HashMap<>();
-        for (PatchSetVerification v : jobs) {
-          if (!reported.containsKey(v.getReporter())) {
-            reported.put(v.getReporter(), v.getGranted());
+      if (filter != null && !filter.isEmpty()) {
+        if (filter.equals("CURRENT") ) {
+          Map<String, Timestamp> reported = Maps.newHashMap();
+          for (PatchSetVerification v : jobs) {
+            if (!reported.containsKey(v.getReporter())) {
+              reported.put(v.getReporter(), v.getGranted());
+            }
           }
-        }
-        for (PatchSetVerification v : jobs) {
-          Timestamp ts = v.getGranted();
-          if (reported.values().contains(ts)) {
-            VerificationInfo info = new VerificationInfo();
-            info.value = v.getValue();
-            info.abstain = v.getAbstain();
-            info.url = v.getUrl();
-            info.name = v.getName();
-            info.reporter = v.getReporter();
-            info.comment = v.getComment();
-            info.granted = v.getGranted();
-            info.category = v.getCategory();
-            info.duration = v.getDuration();
-            out.put(v.getJobId().get(), info);
+          for (PatchSetVerification v : jobs) {
+            Timestamp ts = v.getGranted();
+            if (reported.values().contains(ts)) {
+              VerificationInfo info = new VerificationInfo();
+              info.value = v.getValue();
+              info.abstain = v.getAbstain();
+              info.url = v.getUrl();
+              info.name = v.getName();
+              info.reporter = v.getReporter();
+              info.comment = v.getComment();
+              info.granted = v.getGranted();
+              info.category = v.getCategory();
+              info.duration = v.getDuration();
+              out.put(v.getJobId().get(), info);
+            }
           }
-        }
+        } else if (filter.equals("FAILED") ) {
+            for (PatchSetVerification v : jobs) {
+              if (v.getValue() < 0) {
+                VerificationInfo info = new VerificationInfo();
+                info.value = v.getValue();
+                info.abstain = v.getAbstain();
+                info.url = v.getUrl();
+                info.name = v.getName();
+                info.reporter = v.getReporter();
+                info.comment = v.getComment();
+                info.granted = v.getGranted();
+                info.category = v.getCategory();
+                info.duration = v.getDuration();
+                out.put(v.getJobId().get(), info);
+              }
+            }
+          }
       } else {
         // show all reports
         for (PatchSetVerification v : jobs) {
diff --git a/src/main/resources/Documentation/rest-api-changes.md b/src/main/resources/Documentation/rest-api-changes.md
index 91123ca..2012f92 100644
--- a/src/main/resources/Documentation/rest-api-changes.md
+++ b/src/main/resources/Documentation/rest-api-changes.md
@@ -73,9 +73,32 @@
 ### <a id="verification-options"> Verification Options
 Verifications Options
 
-Current(c)::
-Limit the results to the most current list of reports that were reported by
-each reporter.
+Sort(s)::
+Sort the results by a field.
+
+|Field Name |Description|
+|:----------|:----------|
+|NAME       |Sort job name in ascending order|
+|REPORTER   |Sort reporter in ascending order|
+
+*__Note__: Fields are also sorted by the time the job was saved in descending
+order. 
+
+#### Request
+
+```
+  GET /changes/100/revisions/1/@PLUGIN@~verifications/?sort=REPORTER HTTP/1.0
+```
+
+
+Filter(f)::
+
+|Field Name |Description|
+|:----------|:----------|
+|CURRENT    |Limit the results to the most current list of reports|
+|FAILED     |Limit the results to only failed jobs|
+
+#### Example
 
 Assuming "Jenkins Check" and "ACME CI" published multiple reports to Gerrit.
 Retrieve the most current report(s) by each reporter:
@@ -83,7 +106,7 @@
 #### Request
 
 ```
-  GET /changes/100/revisions/1/@PLUGIN@~verifications/?current HTTP/1.0
+  GET /changes/100/revisions/1/@PLUGIN@~verifications/?sort=REPORTER&filter=CURRENT HTTP/1.0
 ```
 
 #### Response
@@ -95,16 +118,6 @@
 
   )]}'
   {
-    "5081c5e5-e101-43eb-8e59-4e197f22a0d0"": {
-      "name": "gate-horizon-pep8",
-      "url": "https://ci.host.com/jobs/gate-horizon-pep8/2711",
-      "value": -1,
-      "reporter": "Jenkins Check",
-      "comment": "Failed",
-      "category": "cloud server",
-      "duration": "3m 10s"
-      "granted": "15 Mar 2016 08:10:41",
-    },
     "2a359a73-31e7-4f81-b295-ae0e20615da6": {
       "name": "gate-horizon-python27",
       "url": "https://ci.host.com/jobs/gate-horizon-python27/1711",
@@ -115,6 +128,16 @@
       "category": "third party",
       "duration": "7m 40s"
       "granted": "15 Mar 2016 08:30:16"
+    },
+    "5081c5e5-e101-43eb-8e59-4e197f22a0d0"": {
+      "name": "gate-horizon-pep8",
+      "url": "https://ci.host.com/jobs/gate-horizon-pep8/2711",
+      "value": -1,
+      "reporter": "Jenkins Check",
+      "comment": "Failed",
+      "category": "cloud server",
+      "duration": "3m 10s"
+      "granted": "15 Mar 2016 08:10:41",
     }
   }
 ```