/**
*    Copyright 2011, Big Switch Networks, Inc. 
*    Originally created by David Erickson, Stanford University
* 
*    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 net.floodlightcontroller.core.web;

import java.lang.Thread.State;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.types.MacVlanPair;

import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.statistics.OFStatistics;
import org.openflow.protocol.statistics.OFStatisticsType;
import org.openflow.util.HexString;
import org.restlet.resource.Get;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Return switch statistics information for all switches
 * @author readams
 */
public class AllSwitchStatisticsResource extends SwitchResourceBase {
    protected final static Logger log = 
        LoggerFactory.getLogger(AllSwitchStatisticsResource.class);
    
    @Get("json")
    public Map<String, Object> retrieve() {    
        String statType = (String) getRequestAttributes().get("statType");
        return retrieveInternal(statType);
    }
        
    public Map<String, Object> retrieveInternal(String statType) {
        HashMap<String, Object> model = new HashMap<String, Object>();

        OFStatisticsType type = null;
        REQUESTTYPE rType = null;
        
        if (statType.equals("port")) {
            type = OFStatisticsType.PORT;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("queue")) {
            type = OFStatisticsType.QUEUE;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("flow")) {
            type = OFStatisticsType.FLOW;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("aggregate")) {
            type = OFStatisticsType.AGGREGATE;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("desc")) {
            type = OFStatisticsType.DESC;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("table")) {
            type = OFStatisticsType.TABLE;
            rType = REQUESTTYPE.OFSTATS;
        } else if (statType.equals("features")) {
            rType = REQUESTTYPE.OFFEATURES;
        } else {
            return model;
        }
        
        IFloodlightProviderService floodlightProvider = 
                (IFloodlightProviderService)getContext().getAttributes().
                    get(IFloodlightProviderService.class.getCanonicalName());        
        Long[] switchDpids = floodlightProvider.getSwitches().keySet().toArray(new Long[0]);
        List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.length);
        List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
        GetConcurrentStatsThread t;
        for (Long l : switchDpids) {
            t = new GetConcurrentStatsThread(l, rType, type);
            activeThreads.add(t);
            t.start();
        }
        
        // Join all the threads after the timeout. Set a hard timeout
        // of 12 seconds for the threads to finish. If the thread has not
        // finished the switch has not replied yet and therefore we won't 
        // add the switch's stats to the reply.
        for (int iSleepCycles = 0; iSleepCycles < 12; iSleepCycles++) {
            for (GetConcurrentStatsThread curThread : activeThreads) {
                if (curThread.getState() == State.TERMINATED) {
                    if (rType == REQUESTTYPE.OFSTATS) {
                        model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getStatisticsReply());
                    } else if (rType == REQUESTTYPE.OFFEATURES) {
                        model.put(HexString.toHexString(curThread.getSwitchId()), curThread.getFeaturesReply());
                    }
                    pendingRemovalThreads.add(curThread);
                }
            }
            
            // remove the threads that have completed the queries to the switches
            for (GetConcurrentStatsThread curThread : pendingRemovalThreads) {
                activeThreads.remove(curThread);
            }
            // clear the list so we don't try to double remove them
            pendingRemovalThreads.clear();
            
            // if we are done finish early so we don't always get the worst case
            if (activeThreads.isEmpty()) {
                break;
            }
            
            // sleep for 1 s here
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error("Interrupted while waiting for statistics", e);
            }
        }
        
        return model;
    }
    
    protected class GetConcurrentStatsThread extends Thread {
        private List<OFStatistics> switchReply;
        private long switchId;
        private OFStatisticsType statType;
        private REQUESTTYPE requestType;
        private OFFeaturesReply featuresReply;
        private Map<MacVlanPair, Short> switchTable;
        
        public GetConcurrentStatsThread(long switchId, REQUESTTYPE requestType, OFStatisticsType statType) {
            this.switchId = switchId;
            this.requestType = requestType;
            this.statType = statType;
            this.switchReply = null;
            this.featuresReply = null;
            this.switchTable = null;
        }
        
        public List<OFStatistics> getStatisticsReply() {
            return switchReply;
        }
        
        public OFFeaturesReply getFeaturesReply() {
            return featuresReply;
        }
        
        public Map<MacVlanPair, Short> getSwitchTable() {
            return switchTable;
        }
        
        public long getSwitchId() {
            return switchId;
        }
        
        public void run() {
            if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
                switchReply = getSwitchStatistics(switchId, statType);
            } else if (requestType == REQUESTTYPE.OFFEATURES) {
                featuresReply = getSwitchFeaturesReply(switchId);
            }
        }
    }
}
