Enhance CLI command 'tablestats' to support P4 switch

Change-Id: Icb7bae93840bac1ad8d49240f61a4f5bf08dac4c
(cherry picked from commit 1a4333c51c4285bf32d61434b27fa3070336935c)
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
index 53423d3..bf34437 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
@@ -24,10 +24,36 @@
 public final class DefaultTableStatisticsEntry implements TableStatisticsEntry {
 
     private final DeviceId deviceId;
-    private final int tableId;
+    private final TableId tableId;
     private final long activeFlowEntries;
     private final long packetsLookedupCount;
     private final long packetsMatchedCount;
+    private final long maxSize;
+    private static final Long NOT_PRESENT = (long) -1;
+
+    /**
+     * Default table statistics constructor.
+     *
+     * @param deviceId device identifier
+     * @param tableId index table identifier
+     * @param activeFlowEntries number of active flow entries in the table
+     * @param packetsLookedupCount number of packets looked up in table
+     * @param packetsMatchedCount number of packets that hit table
+     * @deprecated since 1.15, suggest using the Builder class.
+     */
+    @Deprecated
+    public DefaultTableStatisticsEntry(DeviceId deviceId,
+                                       int  tableId,
+                                       long activeFlowEntries,
+                                       long packetsLookedupCount,
+                                       long packetsMatchedCount) {
+        this.deviceId = checkNotNull(deviceId);
+        this.tableId = IndexTableId.of(tableId);
+        this.activeFlowEntries = activeFlowEntries;
+        this.packetsLookedupCount = packetsLookedupCount;
+        this.packetsMatchedCount = packetsMatchedCount;
+        this.maxSize = NOT_PRESENT;
+    }
 
     /**
      * Default table statistics constructor.
@@ -37,17 +63,20 @@
      * @param activeFlowEntries number of active flow entries in the table
      * @param packetsLookedupCount number of packets looked up in table
      * @param packetsMatchedCount number of packets that hit table
+     * @param maxSize maximum size of this table
      */
-    public DefaultTableStatisticsEntry(DeviceId deviceId,
-                                  int  tableId,
-                                  long activeFlowEntries,
-                                  long packetsLookedupCount,
-                                  long packetsMatchedCount) {
+    private DefaultTableStatisticsEntry(DeviceId deviceId,
+                                       TableId  tableId,
+                                       long activeFlowEntries,
+                                       long packetsLookedupCount,
+                                       long packetsMatchedCount,
+                                       long maxSize) {
         this.deviceId = checkNotNull(deviceId);
         this.tableId = tableId;
         this.activeFlowEntries = activeFlowEntries;
         this.packetsLookedupCount = packetsLookedupCount;
         this.packetsMatchedCount = packetsMatchedCount;
+        this.maxSize = maxSize;
     }
 
     @Override
@@ -61,6 +90,12 @@
 
     @Override
     public int tableId() {
+        return tableId.type() == TableId.Type.INDEX ? ((IndexTableId) tableId).id() : tableId.hashCode();
+    }
+
+    @Override
+    public TableId table() {
+        //TODO: this is a temporary method, should implement tableId() like this method.
         return tableId;
     }
 
@@ -83,4 +118,73 @@
     public DeviceId deviceId() {
         return deviceId;
     }
-}
+
+    @Override
+    public long maxSize() {
+        return maxSize;
+    }
+
+    @Override
+    public boolean hasPacketsLookedup() {
+        return packetsLookedupCount == NOT_PRESENT ? false : true;
+    }
+
+    @Override
+    public boolean hasMaxSize() {
+        return maxSize == NOT_PRESENT ? false : true;
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder {
+        private DeviceId deviceId;
+        private TableId tableId;
+        private Long activeFlowEntries;
+        private Long packetsMatchedCount;
+        private Long packetsLookedUpCount = NOT_PRESENT;
+        private Long maxSize = NOT_PRESENT;
+
+        public Builder withDeviceId(DeviceId deviceId) {
+            this.deviceId = deviceId;
+            return this;
+        }
+
+        public Builder withTableId(TableId tableId) {
+            this.tableId = tableId;
+            return this;
+        }
+
+        public Builder withActiveFlowEntries(long activeFlowEntries) {
+            this.activeFlowEntries = activeFlowEntries;
+            return this;
+        }
+
+        public Builder withPacketsLookedUpCount(long packetsLookedUpCount) {
+            this.packetsLookedUpCount = packetsLookedUpCount;
+            return this;
+        }
+
+        public Builder withPacketsMatchedCount(long packetsMatchedCount) {
+            this.packetsMatchedCount = packetsMatchedCount;
+            return this;
+        }
+
+        public Builder withMaxSize(long maxSize) {
+            this.maxSize = maxSize;
+            return this;
+        }
+
+        public TableStatisticsEntry build() {
+            checkNotNull(deviceId, "DeviceId cannot be null");
+            checkNotNull(tableId, "TableId cannot be null");
+            checkNotNull(activeFlowEntries, "ActiveFlowEntries cannot be null");
+            checkNotNull(packetsMatchedCount, "PacketsMatchedCount cannot be null");
+
+            return new DefaultTableStatisticsEntry(deviceId, tableId, activeFlowEntries, packetsLookedUpCount,
+                    packetsMatchedCount, maxSize);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TableStatisticsEntry.java b/core/api/src/main/java/org/onosproject/net/flow/TableStatisticsEntry.java
index 505d535..1b39146 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TableStatisticsEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TableStatisticsEntry.java
@@ -30,13 +30,21 @@
     DeviceId  deviceId();
 
     /**
-     * Returns the table number.
+     * Returns the integer table id.
      *
-     * @return table number
+     * @return integer table id
      */
+    @Deprecated
     int  tableId();
 
     /**
+     * Returns the table id.
+     *
+     * @return table id
+     */
+    TableId table();
+
+    /**
      * Returns the number of active flow entries in this table.
      *
      * @return the number of active flow entries
@@ -56,4 +64,26 @@
      * @return the number of packets that successfully matched in the table
      */
     long packetsMatched();
-}
+
+    /**
+     * Returns the maximum size of this table.
+     *
+     * @return the maximum size of this table
+     */
+    long maxSize();
+
+    /**
+     * To check whether packetLookedUp is present in this TableStatisticsEntry.
+     *
+     * @return true if packetLookedUp is present, otherwise false;
+     */
+    boolean hasPacketsLookedup();
+
+    /**
+     * To check whether maxSize is present in this TableStatisticsEntry.
+     *
+     * @return true if maxSize is present, otherwise false;
+     */
+    boolean hasMaxSize();
+
+}
\ No newline at end of file
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java
index efd1d2c..f1af62b 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/TableStatisticsEntryCodec.java
@@ -33,7 +33,7 @@
         checkNotNull(entry, "Table Statistics entry cannot be null");
 
         final ObjectNode result = context.mapper().createObjectNode()
-                .put("tableId", entry.tableId())
+                .put("tableId", entry.table().toString())
                 .put("deviceId", entry.deviceId().toString())
                 .put("activeEntries", entry.activeFlowEntries())
                 .put("packetsLookedUp", entry.packetsLookedup())
@@ -43,4 +43,3 @@
     }
 
 }
-