Filters intent list before installation

Change-Id: I6f73ff65ab7e31fac8e9a6f28f20f0119e24793d
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java
index 68fc06e..17b4653 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java
@@ -36,6 +36,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
@@ -200,8 +201,64 @@
             this.toInstall = toInstall;
             this.successConsumer = successConsumer;
             this.errorConsumer = errorConsumer;
-            prepareIntentData(toUninstall, Direction.REMOVE);
-            prepareIntentData(toInstall, Direction.ADD);
+            prepareIntentData(toUninstall, toInstall);
+        }
+
+        private void prepareIntentData(Optional<IntentData> uninstallData,
+                                       Optional<IntentData> installData) {
+            if (!installData.isPresent() && !uninstallData.isPresent()) {
+                return;
+            } else if (!installData.isPresent()) {
+                prepareIntentData(uninstallData, Direction.REMOVE);
+            } else if (!uninstallData.isPresent()) {
+                prepareIntentData(installData, Direction.ADD);
+            } else {
+                IntentData uninstall = uninstallData.get();
+                IntentData install = installData.get();
+                List<Intent> uninstallIntents = new ArrayList<>();
+                uninstallIntents.addAll(uninstall.installables());
+                List<Intent> installIntents = new ArrayList<>();
+                installIntents.addAll(install.installables());
+
+                checkState(uninstallIntents.stream().allMatch(this::isSupported),
+                           "Unsupported installable intents detected");
+                checkState(installIntents.stream().allMatch(this::isSupported),
+                           "Unsupported installable intents detected");
+
+                //TODO: Filter FlowObjective intents
+                // Filter out same intents and intents with same flow rules
+                Iterator<Intent> iterator = installIntents.iterator();
+                while (iterator.hasNext()) {
+                    Intent installIntent = iterator.next();
+                    uninstallIntents.stream().filter(uIntent -> {
+                        if (uIntent.equals(installIntent)) {
+                            return true;
+                        } else if (uIntent instanceof FlowRuleIntent && installIntent instanceof FlowRuleIntent) {
+                            return ((FlowRuleIntent) uIntent).flowRules()
+                                    .containsAll(((FlowRuleIntent) installIntent).flowRules());
+                        } else {
+                            return false;
+                        }
+                    }).findFirst().ifPresent(common -> {
+                        uninstallIntents.remove(common);
+                        iterator.remove();
+                    });
+                }
+
+                final IntentData newUninstall = new IntentData(uninstall, uninstallIntents);
+                final IntentData newInstall = new IntentData(install, installIntents);
+
+                trackerService.removeTrackedResources(newUninstall.key(), newUninstall.intent().resources());
+                uninstallIntents.forEach(installable ->
+                                                 trackerService.removeTrackedResources(newUninstall.intent().key(),
+                                                                                       installable.resources()));
+                trackerService.addTrackedResources(newInstall.key(), newInstall.intent().resources());
+                installIntents.forEach(installable ->
+                                               trackerService.addTrackedResources(newInstall.key(),
+                                                                                  installable.resources()));
+                prepareIntents(uninstallIntents, Direction.REMOVE);
+                prepareIntents(installIntents, Direction.ADD);
+            }
         }
 
         /**