[VOL-5596]:OLT offload APP statistics for OLT display in voltctl

Signed-off-by: balaji.nagarajan <balaji.nagarajan@radisys.com>
Change-Id: I5aeffb25277ee6c57adf1b594a96c1f80f713e8f
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index 91b1d59..340889b 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -20,6 +20,7 @@
 	"encoding/json"
 	"fmt"
 	"os"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -202,6 +203,39 @@
  ReceivedPayloadBytes:   {{.ReceivedPayloadBytes}}
  TransmittedPayloadBytes:{{.TransmittedPayloadBytes}}
  EncryptionKeyErrors:    {{.EncryptionKeyErrors}}{{end}}`
+	DEFAULT_OFFLOAD_APP_STATS_DHCPv4_FORMAT = `AdditionalStats:
+{{index . "additional_stats"}}
+InBadPacketsFromClient: {{index . "in_bad_packets_from_client"}}
+InBadPacketsFromServer: {{index . "in_bad_packets_from_server"}}
+InPacketsFromClient: {{index . "in_packets_from_client"}}
+InPacketsFromServer: {{index . "in_packets_from_server"}}
+OutPacketsToServer: {{index . "out_packets_to_server"}}
+OutPacketsToClient: {{index . "out_packets_to_client"}}
+Option_82InsertedPacketsToServer: {{index . "option_82_inserted_packets_to_server"}}
+Option_82RemovedPacketsToClient: {{index . "option_82_removed_packets_to_client"}}
+Option_82NotInsertedToServer: {{index . "option_82_not_inserted_to_server"}}`
+	DEFAULT_OFFLOAD_APP_STATS_DHCPv6_FORMAT = `AdditionalStats:
+{{index . "additional_stats"}}
+InBadPacketsFromClient: {{index . "in_bad_packets_from_client"}}
+InBadPacketsFromServer: {{index . "in_bad_packets_from_server"}}
+Option_17InsertedPacketsToServer: {{index . "option_17_inserted_packets_to_server"}}
+Option_17RemovedPacketsToClient: {{index . "option_17_removed_packets_to_client"}}
+Option_18InsertedPacketsToServer: {{index . "option_18_inserted_packets_to_server"}}
+Option_18RemovedPacketsToClient: {{index . "option_18_removed_packets_to_client"}}
+Option_37InsertedPacketsToServer: {{index . "option_37_inserted_packets_to_server"}}
+Option_37RemovedPacketsToClient: {{index . "option_37_removed_packets_to_client"}}
+OutgoingMtuExceededPacketsFromClient: {{index . "outgoing_mtu_exceeded_packets_from_client"}}`
+	DEFAULT_OFFLOAD_APP_STATS_PPPOE_IA_FORMAT = `AdditionalStats:
+{{index . "additional_stats"}}
+InErrorPacketsFromClient: {{index . "in_error_packets_from_client"}}
+InErrorPacketsFromServer: {{index . "in_error_packets_from_server"}}
+InPacketsFromClient: {{index . "in_packets_from_client"}}
+InPacketsFromServer: {{index . "in_packets_from_server"}}
+OutPacketsToServer: {{index . "out_packets_to_server"}}
+OutPacketsToClient: {{index . "out_packets_to_client"}}
+VendorSpecificTagInsertedPacketsToServer: {{index . "vendor_specific_tag_inserted_packets_to_server"}}
+VendorSpecificTagRemovedPacketsToClient: {{index . "vendor_specific_tag_removed_packets_to_client"}}
+OutgoingMtuExceededPacketsFromClient: {{index . "outgoing_mtu_exceeded_packets_from_client"}}`
 )
 
 type DeviceList struct {
@@ -2380,6 +2414,8 @@
 
 	// Process the response data
 	stats, formatStr := buildOffloadAppStatsOutputFormat(rv.GetResponse().GetOffloadedAppsStats())
+
+	formatAdditionalStats(stats)
 	outputFormat := CharReplacer.Replace(options.Format)
 	if outputFormat == "" {
 		outputFormat = GetCommandOptionWithDefault("device-get-offload-app-stats", "format", formatStr)
@@ -2397,6 +2433,32 @@
 	return nil
 }
 
+func formatAdditionalStats(stats map[string]interface{}) {
+	if v, ok := stats["additional_stats"]; ok {
+		if m, ok := v.(map[string]interface{}); ok {
+
+			keys := make([]string, 0, len(m))
+			for k := range m {
+				keys = append(keys, k)
+			}
+
+			sort.Strings(keys)
+
+			var b strings.Builder
+
+			for _, k := range keys {
+				b.WriteString(fmt.Sprintf(
+					"  %-65s : %v\n",
+					k,
+					m[k],
+				))
+			}
+
+			stats["additional_stats"] = b.String()
+		}
+	}
+}
+
 func (options *SetOffloadApp) Execute(args []string) error {
 	conn, err := NewConnection()
 	if err != nil {
diff --git a/internal/pkg/commands/stats.go b/internal/pkg/commands/stats.go
index 26697ac..2cdfe57 100644
--- a/internal/pkg/commands/stats.go
+++ b/internal/pkg/commands/stats.go
@@ -196,7 +196,6 @@
 
 func buildOffloadAppStatsOutputFormat(stats *extension.GetOffloadedAppsStatisticsResponse) (map[string]interface{}, string) {
 	formatStr := "table" // Default format
-
 	if stats == nil {
 		return map[string]interface{}{
 			"error": "No stats available in response",
@@ -216,7 +215,7 @@
 			"option_82_removed_packets_to_client":  data.Dhcpv4RaStats.Option_82RemovedPacketsToClient,
 			"option_82_not_inserted_to_server":     data.Dhcpv4RaStats.Option_82NotInsertedToServer,
 			"additional_stats":                     convertMapStringToInterface(data.Dhcpv4RaStats.AdditionalStats),
-		}, formatStr
+		}, DEFAULT_OFFLOAD_APP_STATS_DHCPv4_FORMAT
 
 	case *extension.GetOffloadedAppsStatisticsResponse_Dhcpv6RaStats:
 		return map[string]interface{}{
@@ -226,11 +225,11 @@
 			"option_17_removed_packets_to_client":       data.Dhcpv6RaStats.Option_17RemovedPacketsToClient,
 			"option_18_inserted_packets_to_server":      data.Dhcpv6RaStats.Option_18InsertedPacketsToServer,
 			"option_18_removed_packets_to_client":       data.Dhcpv6RaStats.Option_18RemovedPacketsToClient,
-			"option_37_inserted_packets_to_server":      data.Dhcpv6RaStats.Option_18InsertedPacketsToServer,
-			"option_37_removed_packets_to_client":       data.Dhcpv6RaStats.Option_18RemovedPacketsToClient,
+			"option_37_inserted_packets_to_server":      data.Dhcpv6RaStats.Option_37InsertedPacketsToServer,
+			"option_37_removed_packets_to_client":       data.Dhcpv6RaStats.Option_37RemovedPacketsToClient,
 			"outgoing_mtu_exceeded_packets_from_client": data.Dhcpv6RaStats.OutgoingMtuExceededPacketsFromClient,
 			"additional_stats":                          convertMapStringToInterface(data.Dhcpv6RaStats.AdditionalStats),
-		}, formatStr
+		}, DEFAULT_OFFLOAD_APP_STATS_DHCPv6_FORMAT
 
 	case *extension.GetOffloadedAppsStatisticsResponse_PppoeIaStats:
 		return map[string]interface{}{
@@ -244,7 +243,7 @@
 			"vendor_specific_tag_removed_packets_to_client":  data.PppoeIaStats.VendorSpecificTagRemovedPacketsToClient,
 			"outgoing_mtu_exceeded_packets_from_client":      data.PppoeIaStats.OutgoingMtuExceededPacketsFromClient,
 			"additional_stats":                               convertMapStringToInterface(data.PppoeIaStats.AdditionalStats),
-		}, formatStr
+		}, DEFAULT_OFFLOAD_APP_STATS_PPPOE_IA_FORMAT
 
 	default:
 		return map[string]interface{}{