/*
 * Copyright 2016 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.provider.of.message.impl;

import com.codahale.metrics.Meter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.onlab.metrics.MetricsComponent;
import org.onlab.metrics.MetricsFeature;
import org.onlab.metrics.MetricsService;
import org.onosproject.cpman.ControlMessage;
import org.onosproject.cpman.DefaultControlMessage;
import org.onosproject.cpman.message.ControlMessageProviderService;
import org.onosproject.net.DeviceId;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFType;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

import static org.onosproject.provider.of.message.impl.OpenFlowControlMessageMapper.lookupControlMessageType;

/**
 * Collects the OpenFlow messages and aggregates using MetricsService.
 */
public class OpenFlowControlMessageAggregator implements Runnable {

    private static final Set<OFType> OF_TYPE_SET =
            ImmutableSet.of(OFType.PACKET_IN, OFType.PACKET_OUT, OFType.FLOW_MOD,
                    OFType.FLOW_REMOVED, OFType.STATS_REQUEST, OFType.STATS_REPLY);

    private final Map<OFType, Meter> rateMeterMap = Maps.newHashMap();
    private final Map<OFType, Meter> countMeterMap = Maps.newHashMap();

    private final DeviceId deviceId;
    private final ControlMessageProviderService providerService;

    private static final String RATE_NAME = "rate";
    private static final String COUNT_NAME = "count";

    private Collection<ControlMessage> controlMessages = new ArrayList<>();

    // TODO: this needs to be configurable
    private static final int EXECUTE_PERIOD_IN_SECOND = 60;

    /**
     * Generates an OpenFlow message aggregator instance.
     * The instance is for aggregating a specific OpenFlow message
     * type of an OpenFlow switch.
     *
     * @param metricsService metrics service reference object
     * @param providerService control message provider service reference object
     * @param deviceId device identification
     */
    public OpenFlowControlMessageAggregator(MetricsService metricsService,
                                            ControlMessageProviderService providerService,
                                            DeviceId deviceId) {
        MetricsComponent mc = metricsService.registerComponent(deviceId.toString());

        OF_TYPE_SET.forEach(type -> {
            MetricsFeature metricsFeature = mc.registerFeature(type.toString());
            Meter rateMeter = metricsService.createMeter(mc, metricsFeature, RATE_NAME);
            Meter countMeter = metricsService.createMeter(mc, metricsFeature, COUNT_NAME);
            rateMeterMap.put(type, rateMeter);
            countMeterMap.put(type, countMeter);
        });

        this.deviceId = deviceId;
        this.providerService = providerService;
    }

    /**
     * Increments the meter rate by n, and the meter count by 1.
     *
     * @param msg OpenFlow message
     */
    public void increment(OFMessage msg) {
        rateMeterMap.get(msg.getType()).mark(msg.toString().length());
        countMeterMap.get(msg.getType()).mark(1);
    }

    @Override
    public void run() {
        // update 1 minute statistic information of all control messages
        OF_TYPE_SET.forEach(type -> controlMessages.add(
                new DefaultControlMessage(lookupControlMessageType(type),
                        getLoad(type), getRate(type), getCount(type),
                        System.currentTimeMillis())));
        providerService.updateStatsInfo(deviceId,
                Collections.unmodifiableCollection(controlMessages));
    }

    /**
     * Returns the average load value.
     *
     * @param type OpenFlow message type
     * @return load value
     */
    private long getLoad(OFType type) {
        return (long) rateMeterMap.get(type).getOneMinuteRate() /
                (long) countMeterMap.get(type).getOneMinuteRate();
    }

    /**
     * Returns the average meter rate within recent 1 minute.
     *
     * @param type OpenFlow message type
     * @return rate value
     */
    private long getRate(OFType type) {
        return (long) rateMeterMap.get(type).getOneMinuteRate();
    }

    /**
     * Returns the average meter count within recent 1 minute.
     *
     * @param type OpenFlow message type
     * @return count value
     */
    private long getCount(OFType type) {
        return (long) countMeterMap.get(type).getOneMinuteRate() *
                EXECUTE_PERIOD_IN_SECOND;
    }
}
