VOL-4559: Delete the TP Instance and TP ID first once all the GEM
references are cleared before checking for other TP instances with
the same alloc-id in case of instance-control is single-instance per ONU.
Also has more fixes related to handling of instance-control onu single-
instance during setup and removal of schedulers/queues.

Also fix issue related to stale data after device delete for mcast
queues.

Change-Id: Iaca358128e91c3f1ba23dd4bea3d05dccc67bb02
diff --git a/internal/pkg/resourcemanager/resourcemanager.go b/internal/pkg/resourcemanager/resourcemanager.go
index e9809f2..476bbf5 100755
--- a/internal/pkg/resourcemanager/resourcemanager.go
+++ b/internal/pkg/resourcemanager/resourcemanager.go
@@ -508,18 +508,22 @@
 // for the given OLT device.
 // The caller should ensure that this is a blocking call and this operation is serialized for
 // the ONU so as not cause resource corruption since there are no mutexes used here.
+// Setting freeFromResourcePool to false will not clear it from the resource pool but only
+// clear it for the given pon/onu/uni
 func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, intfID uint32, onuID uint32,
-	uniID uint32, allocID uint32) {
+	uniID uint32, allocID uint32, freeFromResourcePool bool) {
 
 	rsrcMgr.RemoveAllocIDForOnu(ctx, intfID, onuID, uniID, allocID)
-	allocIDs := make([]uint32, 0)
-	allocIDs = append(allocIDs, allocID)
-	if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
-		logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
-			"intf-id": intfID,
-			"onu-id":  onuID,
-			"err":     err.Error(),
-		})
+	if freeFromResourcePool {
+		allocIDs := make([]uint32, 0)
+		allocIDs = append(allocIDs, allocID)
+		if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
+			logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
+				"intf-id": intfID,
+				"onu-id":  onuID,
+				"err":     err.Error(),
+			})
+		}
 	}
 }
 
@@ -1301,6 +1305,17 @@
 	return nil
 }
 
+//DeleteMcastQueueForIntf deletes multicast queue info for the current pon interface from kvstore
+func (rsrcMgr *OpenOltResourceMgr) DeleteMcastQueueForIntf(ctx context.Context) {
+	path := McastQueuesForIntf
+
+	if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
+		logger.Errorw(ctx, "Failed to delete multicast queue info from kvstore", log.Fields{"err": err, "interfaceId": rsrcMgr.PonIntfID})
+		return
+	}
+	logger.Debugw(ctx, "deleted multicast queue info from KV store successfully", log.Fields{"interfaceId": rsrcMgr.PonIntfID})
+}
+
 //AddFlowGroupToKVStore adds flow group into KV store
 func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
 	var Value []byte
diff --git a/internal/pkg/resourcemanager/resourcemanager_test.go b/internal/pkg/resourcemanager/resourcemanager_test.go
index c4a6751..5392eb7 100644
--- a/internal/pkg/resourcemanager/resourcemanager_test.go
+++ b/internal/pkg/resourcemanager/resourcemanager_test.go
@@ -864,6 +864,23 @@
 	}
 }
 
+func TestOpenOltResourceMgr_DeleteMcastQueueForIntf(t *testing.T) {
+	tests := []struct {
+		name   string
+		fields *fields
+	}{
+		{"DeleteMcastQueueForIntf-1", getResMgr()},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			RsrcMgr := testResMgrObject(tt.fields)
+			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+			defer cancel()
+			RsrcMgr.DeleteMcastQueueForIntf(ctx)
+		})
+	}
+}
+
 func newGroup(groupID uint32, outPorts []uint32) *ofp.OfpGroupEntry {
 	groupDesc := ofp.OfpGroupDesc{
 		Type:    ofp.OfpGroupType_OFPGT_ALL,