package net.floodlightcontroller.offloading;

// import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.ImmutablePort;

import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFStatisticsRequest;
import org.openflow.protocol.statistics.OFFlowStatisticsReply;
import org.openflow.protocol.statistics.OFFlowStatisticsRequest;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.protocol.statistics.OFStatisticsType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SwitchFlowStatistics implements Runnable {

    protected static Logger log = LoggerFactory.getLogger(OffloadingProtocolServer.class);

    private IFloodlightProviderService floodlightProvider;
    // private final ExecutorService executor;

    // private List<OFFlowStatisticsReply> statsReply;
    private Timer timer;
    private long interval;

    private class PrintTask extends TimerTask {
        public void run() {
            printStatistics();
        }
    }

    public SwitchFlowStatistics(IFloodlightProviderService fProvider,
            ExecutorService executor, int printInterval) {
        this.floodlightProvider = fProvider;
        // this.executor = executor;
        this.timer = new Timer();
        this.interval = (long)printInterval;
    }



    @Override
    public void run() {
        timer.schedule(new PrintTask(), (long)2000, this.interval*1000);
    }



    private void printStatistics() {
        // statsReply = new ArrayList<OFFlowStatisticsReply>();
        List<OFStatistics> values = null;
        Future<List<OFStatistics>> future;
        OFFlowStatisticsReply reply;
        float rate;


        // get switch
        Map<Long,IOFSwitch> swMap = floodlightProvider.getAllSwitchMap();

        // Statistics request object for getting flows
        OFStatisticsRequest req = new OFStatisticsRequest();
        req.setStatisticType(OFStatisticsType.FLOW);
        int requestLength = req.getLengthU();
        OFFlowStatisticsRequest specificReq = new OFFlowStatisticsRequest();
        specificReq.setMatch(new OFMatch().setWildcards(0xffffffff));
        specificReq.setTableId((byte) 0xff);

        for (IOFSwitch sw: swMap.values()) {
            try {
                // iterate all the ports
                Collection<ImmutablePort> ports = sw.getEnabledPorts();
                for (ImmutablePort port: ports) {
                    short outPort = port.getPortNumber();
                    specificReq.setOutPort(outPort);
                    req.setStatistics(Collections.singletonList((OFStatistics) specificReq));
                    requestLength += specificReq.getLength();
                    req.setLengthU(requestLength);
                }

                // make the query
                future = sw.queryStatistics(req);
                values = future.get(3, TimeUnit.SECONDS);
                if (values != null) {
                    for (OFStatistics stat : values) {
                        // statsReply.add((OFFlowStatisticsReply) stat);
                        reply = (OFFlowStatisticsReply) stat;
                        rate = (float) reply.getByteCount()
                                    / (reply.getDurationSeconds()
                                    + 1000000000*reply.getDurationNanoseconds());
                        log.info(reply.toString());
                        System.out.println(rate);
                    }
                }
            } catch (Exception e) {
                log.error("Failure retrieving statistics from switch " + sw, e);
            }
        }
    }

}

@@ -2835,24 +2835,67 @@
 rtNumber();%0A
+                    if (outPort %3E 0) %7B%0A    
             
@@ -2931,24 +2931,28 @@
 t(outPort);%0A
+    
             
@@ -3053,16 +3053,20 @@
         
+    
 requestL
@@ -3115,24 +3115,28 @@
             
+  
+  
 req.setLengt
@@ -3154,32 +3154,25 @@
 ength);%0A
-        
+%0A
         
 %7D%0A%0A     
@@ -3159,27 +3159,24 @@
 );%0A%0A        
-%7D%0A%0A
             
@@ -3213,16 +3213,24 @@
         
+        
 future =
@@ -3271,16 +3271,24 @@
         
+     
+   
 values =
@@ -3333,24 +3333,32 @@
             
+        
 if (values !
@@ -3383,24 +3383,32 @@
             
+  
+      
 for (OFStati
@@ -3446,32 +3446,40 @@
                 
+       
+ 
 // statsReply.ad
@@ -3535,16 +3535,24 @@
         
+        
 reply = 
@@ -3605,16 +3605,24 @@
         
+     
+   
 rate = (
@@ -3685,16 +3685,24 @@
         
+        
 / (reply
@@ -3759,16 +3759,24 @@
         
+  
+      
 + 100000
@@ -3833,24 +3833,32 @@
             
+       
+ 
 log.info(rep
@@ -3897,16 +3897,24 @@
         
+        
 System.o
@@ -3927,24 +3927,80 @@
 ntln(rate);%0A
+                            %7D%0A                        %7D%0A
             

fix the port number error caused by getPortNumber()