CLI options: flows (remove), intents (remove/purge; details)

Change-Id: Id084c28451389a46826eced30f03dcce2c1afe86
diff --git a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
index cb48396..e90041f 100644
--- a/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/IntentsListCommand.java
@@ -56,7 +56,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
 
 /**
  * Lists the inventory of intents and their states.
@@ -155,11 +154,21 @@
             required = false, multiValued = false)
     private boolean pending = false;
 
+    @Option(name = "-d", aliases = "--details",
+            description = "Show details for intents, filtered by ID",
+            required = false, multiValued = true)
+    private List<String> intentIds = new ArrayList<>();
+
     @Option(name = "-f", aliases = "--filter",
             description = "Filter intents by specific keyword",
             required = false, multiValued = true)
     private List<String> filter = new ArrayList<>();
 
+    @Option(name = "-r", aliases = "--remove",
+            description = "Remove and purge intents by specific keyword",
+            required = false, multiValued = false)
+    private String remove = null;
+
     private StringFilter contentFilter;
     private IntentService service;
 
@@ -175,6 +184,25 @@
             intents = service.getIntents();
         }
 
+        // Remove intents
+        if (remove != null && !remove.isEmpty()) {
+            filter.add(remove);
+            contentFilter = new StringFilter(filter, StringFilter.Strategy.AND);
+            IntentRemoveCommand intentRemoveCmd = new IntentRemoveCommand();
+            if (!remove.isEmpty()) {
+                intentRemoveCmd.purgeIntentsInteractive(filterIntents(service));
+            }
+            return;
+        }
+
+        // Show detailed intents
+        if (!intentIds.isEmpty()) {
+            IntentDetailsCommand intentDetailsCmd = new IntentDetailsCommand();
+            intentDetailsCmd.detailIntents(intentIds);
+            return;
+        }
+
+        // Show brief intents
         if (intentsSummary || miniSummary) {
             Map<String, IntentSummary> summarized = summarize(intents);
             if (outputJson()) {
@@ -197,6 +225,7 @@
             return;
         }
 
+        // JSON or default output
         if (outputJson()) {
             print("%s", json(intents));
         } else {
@@ -213,6 +242,27 @@
     }
 
     /**
+     * Filter a given list of intents based on the existing content filter.
+     *
+     * @param service IntentService object
+     * @return further filtered list of intents
+     */
+    private List<Intent> filterIntents(IntentService service) {
+        return filterIntents(service.getIntents());
+    }
+
+    /**
+     * Filter a given list of intents based on the existing content filter.
+     *
+     * @param intents Iterable of intents
+     * @return further filtered list of intents
+     */
+    private List<Intent> filterIntents(Iterable<Intent> intents) {
+        return Tools.stream(intents)
+                .filter(i -> contentFilter.filter(i)).collect(Collectors.toList());
+    }
+
+    /**
      * Internal local class to keep track of a single type Intent summary.
      */
     private class IntentSummary {
@@ -246,7 +296,9 @@
         IntentSummary(Intent intent) {
             // remove "Intent" from intentType label
             this(intentType(intent));
-            update(service.getIntentState(intent.key()));
+            if (contentFilter.filter(intent)) {
+                update(service.getIntentState(intent.key()));
+            }
         }
 
         // for identity element, when reducing
@@ -412,7 +464,7 @@
      */
     private Map<String, IntentSummary> summarize(Iterable<Intent> intents) {
         Map<String, List<Intent>> perIntent = Tools.stream(intents)
-            .collect(Collectors.groupingBy(i -> intentType(i)));
+            .collect(Collectors.groupingBy(IntentsListCommand::intentType));
 
         List<IntentSummary> collect = perIntent.values().stream()
             .map(il ->
@@ -571,10 +623,9 @@
     private JsonNode json(Iterable<Intent> intents) {
         ObjectMapper mapper = new ObjectMapper();
         ArrayNode result = mapper.createArrayNode();
-        StreamSupport.stream(intents.spliterator(), false)
+        Tools.stream(intents)
                 .filter(intent -> contentFilter.filter(jsonForEntity(intent, Intent.class).toString()))
                 .forEach(intent -> result.add(jsonForEntity(intent, Intent.class)));
         return result;
     }
-
 }