[VOL-5292] Implementation for fetching the GEM port history Data from the ONT

Change-Id: I4cf22555cbd13bcd5e49e620c8aa8b67cbd2891c
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/internal/pkg/avcfg/onu_uni_tp.go b/internal/pkg/avcfg/onu_uni_tp.go
index d3492a5..0b4a204 100755
--- a/internal/pkg/avcfg/onu_uni_tp.go
+++ b/internal/pkg/avcfg/onu_uni_tp.go
@@ -1059,3 +1059,17 @@
 		delete(onuTP.PAniConfigFsm, k)
 	}
 }
+
+// GetGEMportToAllocIDMappingForONU - function to get the GEM ports and corresponding alloc-id mapping for an ONU
+func (onuTP *OnuUniTechProf) GetGEMportToAllocIDMappingForONU(ctx context.Context, aDeviceID string) map[uint16]uint16 {
+	logger.Debugw(ctx, "getting GEM port to AllocID mapping for the ONU", log.Fields{"device-id": aDeviceID})
+	gemportAllocIdMap := make(map[uint16]uint16)
+	for _, tcontGemList := range onuTP.mapPonAniConfig {
+		for gemPortID := range tcontGemList.mapGemPortParams {
+			gemportAllocIdMap[gemPortID] = tcontGemList.tcontParams.allocID
+
+		}
+	}
+	logger.Debugw(ctx, "Mapping between all the GEM ports to corresponding AllocID", log.Fields{"device-id": aDeviceID, "gemportAllocIDMapping": gemportAllocIdMap})
+	return gemportAllocIdMap
+}
diff --git a/internal/pkg/common/interfaces.go b/internal/pkg/common/interfaces.go
index e761a3d..0465398 100755
--- a/internal/pkg/common/interfaces.go
+++ b/internal/pkg/common/interfaces.go
@@ -192,6 +192,7 @@
 	GetAllBidirectionalGemPortIDsForOnu() []uint16
 	GetNumberOfConfiguredUsGemPorts(ctx context.Context) int
 	SetProfileToDelete(uint8, uint8, bool)
+	GetGEMportToAllocIDMappingForONU(ctx context.Context, aDeviceID string) map[uint16]uint16
 }
 
 // IuniVlanConfigFsm interface to uniVlanConfigFsm
diff --git a/internal/pkg/core/device_handler.go b/internal/pkg/core/device_handler.go
index bab59ef..3d12954 100755
--- a/internal/pkg/core/device_handler.go
+++ b/internal/pkg/core/device_handler.go
@@ -4770,6 +4770,13 @@
 	return resp
 }
 
+// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
+func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
+	resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
+	logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
+	return resp
+}
+
 func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
 	return dh.deviceDeleteCommChan
 }
diff --git a/internal/pkg/core/openonu.go b/internal/pkg/core/openonu.go
index 4d68e8f..75ba35e 100755
--- a/internal/pkg/core/openonu.go
+++ b/internal/pkg/core/openonu.go
@@ -498,6 +498,10 @@
 			resp := handler.getOnuActiveAlarms(ctx)
 			logger.Infow(ctx, "Received response for on demand active alarms request ", log.Fields{"response": resp})
 			return resp, nil
+		case *extension.GetValueRequest_OnuAllocGemStats:
+			resp := handler.getONUGEMStatsInfo(ctx)
+			logger.Infow(ctx, "Received response for on demand active alarms request ", log.Fields{"response": resp})
+			return resp, nil
 		default:
 			return uniprt.PostUniStatusErrResponse(extension.GetValueResponse_UNSUPPORTED), nil
 		}
diff --git a/internal/pkg/pmmgr/onu_metrics_manager.go b/internal/pkg/pmmgr/onu_metrics_manager.go
index 11c6435..b60e5f3 100755
--- a/internal/pkg/pmmgr/onu_metrics_manager.go
+++ b/internal/pkg/pmmgr/onu_metrics_manager.go
@@ -4050,3 +4050,62 @@
 	defer mm.OnuMetricsManagerLock.Unlock()
 	mm.deviceDeletionInProgress = true
 }
+
+// Obtain the ONU GEM counters for the ONU device
+func (mm *OnuMetricsManager) GetONUGEMCounters(ctx context.Context) *extension.SingleGetValueResponse {
+
+	resp := extension.SingleGetValueResponse{
+		Response: &extension.GetValueResponse{
+			Status: extension.GetValueResponse_OK,
+			Response: &extension.GetValueResponse_OnuAllocGemStatsResponse{
+				OnuAllocGemStatsResponse: &extension.GetOnuAllocGemHistoryResponse{},
+			},
+		},
+	}
+
+	if mm.GetdeviceDeletionInProgress() {
+		logger.Infow(ctx, "device already deleted, return", log.Fields{"curr-state": mm.PAdaptFsm.PFsm.Current, "deviceID": mm.deviceID})
+		return nil
+	}
+
+	mm.OnuMetricsManagerLock.RLock()
+	defer mm.OnuMetricsManagerLock.RUnlock()
+
+	gemtoAllocId := mm.pDeviceHandler.GetOnuTP().GetGEMportToAllocIDMappingForONU(ctx, mm.deviceID)
+	allocIDtoGem := make(map[uint16][]uint16)
+	for key, value := range gemtoAllocId {
+		allocIDtoGem[value] = append(allocIDtoGem[value], key)
+	}
+
+	for allocID, gemSlice := range allocIDtoGem {
+		logger.Infow(ctx, "AllocID", log.Fields{"alloc-id": allocID})
+		allocIdGemData := extension.OnuAllocGemHistoryData{
+			OnuAllocIdInfo: &extension.OnuAllocHistoryData{},
+			GemPortInfo:    []*extension.OnuGemPortHistoryData{},
+		}
+		allocIdGemData.OnuAllocIdInfo.AllocId = uint32(allocID)
+
+		// Loop through each element in the slice
+		for _, gem := range gemSlice {
+			logger.Debugw(ctx, "Collecting stats for Gem: ", log.Fields{"GEMID": gem})
+			if metricInfo := mm.collectGemHistoryData(ctx, gem); metricInfo != nil {
+				logger.Infow(ctx, "Metricinfo for GEM", log.Fields{"GEMID": gem, "metricInfo": metricInfo})
+				gemHistoryData := extension.OnuGemPortHistoryData{}
+				gemHistoryData.GemId = uint32(gem)
+				gemHistoryData.TransmittedGEMFrames = uint32(metricInfo.GetMetrics()["transmitted_gem_frames"])
+				gemHistoryData.ReceivedGEMFrames = uint32(metricInfo.GetMetrics()["received_gem_frames"])
+				gemHistoryData.ReceivedPayloadBytes = uint32(metricInfo.GetMetrics()["received_payload_bytes"])
+				gemHistoryData.TransmittedPayloadBytes = uint32(metricInfo.GetMetrics()["transmitted_payload_bytes"])
+				gemHistoryData.EncryptionKeyErrors = uint32(metricInfo.GetMetrics()["encryption_key_errors"])
+				allocIdGemData.GemPortInfo = append(allocIdGemData.GemPortInfo, &gemHistoryData)
+				logger.Debugw(ctx, " allocIdGemData value ", log.Fields{"AllocIDGemData": allocIdGemData})
+
+			}
+		}
+		resp.Response.GetOnuAllocGemStatsResponse().OnuAllocGemHistoryData = append(resp.Response.GetOnuAllocGemStatsResponse().OnuAllocGemHistoryData, &allocIdGemData)
+	}
+
+	logger.Debugw(ctx, "Request to fetch GEM Performance Counters  ", log.Fields{"device-id": mm.deviceID, "response": resp})
+	return &resp
+
+}