/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.net.statistic;

import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.TypedStoredFlowEntry;
import org.onosproject.net.flow.instructions.Instruction;

import java.util.List;
import java.util.Map;

/**
 * Service for obtaining individual flow statistic information about device and link in the system.
 * Basic statistics are obtained from the StatisticService
 */
public interface FlowStatisticService {

    /**
     * Obtain the summary load list for the device with the given link.
     *
     * @param device the Device  to query.
     * @return map of summary flow entry load
     */
    Map<ConnectPoint, SummaryFlowEntryWithLoad> loadSummary(Device device);

    /**
     * Obtain the summary load for the device with the given link or port.
     *
     * @param device the Device to query.
     * @param pNumber the port number to query.
     * @return summary flow entry load
     */
    SummaryFlowEntryWithLoad loadSummary(Device device, PortNumber pNumber);

    /**
     * Obtain the set of the flow type and load list for the device with the given link.
     *
     * @param device the Device  to query.
     * @param liveType the FlowLiveType  to filter, null means no filtering .
     * @param instType the InstructionType to filter, null means no filtering.
     * @return map of flow entry load
     */
    Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadAllByType(Device device,
                                                                  TypedStoredFlowEntry.FlowLiveType liveType,
                                                                  Instruction.Type instType);

    /**
     * Obtain the flow type and load list for the device with the given link or port.
     *
     * @param device the Device to query.
     * @param pNumber the port number of the Device to query
     * @param liveType the FlowLiveType  to filter, null means no filtering .
     * @param instType the InstructionType to filter, null means no filtering.
     * @return list of flow entry load
     */
    List<TypedFlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
                                               TypedStoredFlowEntry.FlowLiveType liveType,
                                               Instruction.Type instType);

    /**
     * Obtain the set of the flow type and load topn list for the device with the given link.
     *
     * @param device the Device  to query.
     * @param liveType the FlowLiveType  to filter, null means no filtering .
     * @param instType the InstructionType to filter, null means no filtering.
     * @param topn the top number to filter, null means no filtering.
     * @return map of flow entry load
     */
    Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadTopnByType(Device device,
                                                                   TypedStoredFlowEntry.FlowLiveType liveType,
                                                                   Instruction.Type instType,
                                                                   int topn);

    /**
     * Obtain the flow type and load topn list for the device with the given link or port.
     *
     * @param device the Device  to query.
     * @param pNumber the port number of the Device to query
     * @param liveType the FlowLiveType  to filter, null means no filtering .
     * @param instType the InstructionType to filter, null means no filtering.
     * @param topn topn //FIXME what?
     * @return list of flow entry load
     */
    List<TypedFlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
                                                TypedStoredFlowEntry.FlowLiveType liveType,
                                                Instruction.Type instType,
                                                int topn);
}


