Deserialize the counter record

Change-Id: Icbfcc6d3072c54e7d49dc474a89f1bfe833e7ede
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterRecord.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterRecord.java
index 8b4091e..c8a7562 100644
--- a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterRecord.java
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/CounterRecord.java
@@ -19,13 +19,15 @@
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
-
+import java.nio.ByteBuffer;
 import org.onlab.packet.BasePacket;
 import org.onlab.packet.DeserializationException;
 import org.onlab.packet.Deserializer;
 
 import com.google.common.base.MoreObjects;
 
+import java.util.function.BiPredicate;
+
 import static com.google.common.base.Preconditions.checkState;
 
 /**
@@ -33,6 +35,8 @@
  */
 public final class CounterRecord extends BasePacket {
 
+    public static final int COUNTER_RECORD_HEADER_LENGTH = 8;
+
     private Type type;
 
     private int length;
@@ -83,9 +87,9 @@
         GENERIC(1, InterfaceCounter.deserializer()),
         ETHERNET(2, EthernetCounter.deserializer()),
         TOKENRING(3, TokenRingCounter.deserializer()),
-        FDDI(4, InterfaceCounter.deserializer()),
+        FDDI(4, FddiCounter.deserializer()),
         VG(5, VgCounter.deserializer()),
-        WAN(6, InterfaceCounter.deserializer()),
+        WAN(6, WanCounter.deserializer()),
         VLAN(7, VlanCounter.deserializer());
 
 
@@ -124,9 +128,27 @@
      *
      * @return data deserializer function
      */
-    public static Deserializer<CounterSample> deserializer() {
+    public static Deserializer<CounterRecord> deserializer() {
         return (data, offset, length) -> {
-            return null;
+            BiPredicate<ByteBuffer, Integer> isValidBuffer = (b, l)
+                    -> b.hasRemaining() && b.remaining() >= l;
+
+            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
+            byte[] ifCounterBytes;
+            if (!isValidBuffer.test(bb, COUNTER_RECORD_HEADER_LENGTH)) {
+                throw new IllegalStateException("Invalid interface counter record buffer size.");
+            }
+
+            int recordLength = bb.remaining();
+            byte[] record = new byte[recordLength];
+            bb.get(record);
+
+            Builder builder = new Builder();
+            return builder.type(Type.getType(bb.getInt()))
+                    .length(bb.getInt())
+                    .counterPacket((CounterPacket) Type.getType(bb.getInt()).getDecoder()
+                            .deserialize(record, 0, recordLength))
+                    .build();
         };
     }
 
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FddiCounter.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FddiCounter.java
new file mode 100644
index 0000000..f025ecd
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/FddiCounter.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.sflow;
+
+import com.google.common.base.MoreObjects;
+
+import org.onlab.packet.Deserializer;
+
+/**
+ * Represents FDDI counters for network interfaces.
+ */
+public final class FddiCounter extends CounterPacket {
+
+    private InterfaceCounter generic;
+
+    private FddiCounter(Builder builder) {
+        this.generic = builder.generic;
+    }
+
+    /**
+     * Gets the generic interface counter.
+     *
+     * @return generic interface counter.
+     */
+    public InterfaceCounter getGeneric() {
+        return generic;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("generic", generic)
+                .toString();
+    }
+
+    /**
+     * Deserializer function for sFlow interface FDDI counter.
+     *
+     * @return deserializer function
+     */
+    public static Deserializer<FddiCounter> deserializer() {
+        return (data, offset, length) -> {
+
+            if (length < InterfaceCounter.INTERFACE_COUNTER_LENGTH) {
+                throw new IllegalStateException("Invalid interface FDDI counter buffer size.");
+            }
+
+            Builder builder = new Builder();
+            return builder.generic(InterfaceCounter.deserializer().deserialize(data,
+                            offset, length))
+                    .build();
+        };
+    }
+
+    /**
+     * Builder pattern to create an instance of InterfaceCounter.
+     */
+    private static class Builder {
+        private InterfaceCounter generic;
+
+        /**
+         * Sets the generic interface counter.
+         *
+         * @param generic the generic interface counter.
+         * @return this builder instance.
+         */
+        public Builder generic(InterfaceCounter generic) {
+            this.generic = generic;
+            return this;
+        }
+
+        /**
+         * Builds an instance of FDDI counter based on the configured parameters.
+         *
+         * @return an instance of FDDI counter.
+         */
+        public FddiCounter build() {
+            return new FddiCounter(this);
+        }
+
+    }
+}
diff --git a/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/WanCounter.java b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/WanCounter.java
new file mode 100644
index 0000000..ba9c8e2
--- /dev/null
+++ b/apps/ipflow-monitor/sflow/api/src/main/java/org/onosproject/sflow/WanCounter.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2024-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.sflow;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Deserializer;
+
+/**
+ * Represents WAN counters for network interfaces.
+ */
+public final class WanCounter extends CounterPacket {
+
+    private InterfaceCounter generic;
+
+    private WanCounter(Builder builder) {
+        this.generic = builder.generic;
+    }
+
+    /**
+     * Gets the generic interface counter.
+     *
+     * @return generic interface counter.
+     */
+    public InterfaceCounter getGeneric() {
+        return generic;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("generic", generic)
+                .toString();
+    }
+
+    /**
+     * Deserializer function for sFlow interface WAN counter.
+     *
+     * @return deserializer function
+     */
+    public static Deserializer<WanCounter> deserializer() {
+        return (data, offset, length) -> {
+
+            if (length < InterfaceCounter.INTERFACE_COUNTER_LENGTH) {
+                throw new IllegalStateException("Invalid interface WAN counter buffer size.");
+            }
+
+            Builder builder = new Builder();
+            return builder.generic(InterfaceCounter.deserializer().deserialize(data,
+                            offset, length))
+                    .build();
+        };
+    }
+
+    /**
+     * Builder pattern to create an instance of InterfaceCounter.
+     */
+    private static class Builder {
+        private InterfaceCounter generic;
+
+        /**
+         * Sets the generic interface counter.
+         *
+         * @param generic the generic interface counter.
+         * @return this builder instance.
+         */
+        public Builder generic(InterfaceCounter generic) {
+            this.generic = generic;
+            return this;
+        }
+
+        /**
+         * Builds an instance of WAN counter based on the configured parameters.
+         *
+         * @return an instance of WAN counter.
+         */
+        public WanCounter build() {
+            return new WanCounter(this);
+        }
+
+    }
+}