/*
 * 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.flow.FlowEntry;
import org.onosproject.net.flow.TypedStoredFlowEntry;
import org.onosproject.net.flow.DefaultTypedFlowEntry;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Load of flow entry of flow live type.
 */
public class TypedFlowEntryWithLoad {
    private ConnectPoint cp;
    private TypedStoredFlowEntry tfe;
    private Load load;

    //TODO: make this variables class, and share with NewAdaptivceFlowStatsCollector class
    private static final int CAL_AND_POLL_INTERVAL = 5; // means SHORT_POLL_INTERVAL
    private static final int MID_POLL_INTERVAL = 10;
    private static final int LONG_POLL_INTERVAL = 15;


    public TypedFlowEntryWithLoad(ConnectPoint cp, TypedStoredFlowEntry tfe, Load load) {
        this.cp = cp;
        this.tfe = tfe;
        this.load = load;
    }

    public TypedFlowEntryWithLoad(ConnectPoint cp, TypedStoredFlowEntry tfe) {
        this.cp = cp;
        this.tfe = tfe;
        this.load = new DefaultLoad(tfe.bytes(), 0, typedPollInterval(tfe));
    }

    public TypedFlowEntryWithLoad(ConnectPoint cp, FlowEntry fe) {
        this.cp = cp;
        this.tfe = newTypedStoredFlowEntry(fe);
        this.load = new DefaultLoad(fe.bytes(), 0, typedPollInterval(this.tfe));
    }

    public ConnectPoint connectPoint() {
        return cp;
    }
    public TypedStoredFlowEntry typedStoredFlowEntry() {
        return tfe;
    }
    public Load load() {
        return load;
    }
    public void setLoad(Load load) {
        this.load = load;
    }

    /**
     * Returns short polling interval.
     */
    public static int shortPollInterval() {
        return CAL_AND_POLL_INTERVAL;
    }

    /**
     * Returns mid polling interval.
     */
    public static int midPollInterval() {
        return MID_POLL_INTERVAL;
    }

    /**
     * Returns long polling interval.
     */
    public static int longPollInterval() {
        return LONG_POLL_INTERVAL;
    }

    /**
     * Returns average polling interval.
     */
    public static int avgPollInterval() {
        return (CAL_AND_POLL_INTERVAL + MID_POLL_INTERVAL + LONG_POLL_INTERVAL) / 3;
    }

    /**
     * Returns current typed flow entry's polling interval.
     *
     * @param tfe typed flow entry
     */
    public static long typedPollInterval(TypedStoredFlowEntry tfe) {
        checkNotNull(tfe, "TypedStoredFlowEntry cannot be null");

        switch (tfe.flowLiveType()) {
            case LONG_FLOW:
                return LONG_POLL_INTERVAL;
            case MID_FLOW:
                return MID_POLL_INTERVAL;
            case SHORT_FLOW:
            case IMMEDIATE_FLOW:
            default:
                return CAL_AND_POLL_INTERVAL;
        }
    }

    /**
     * Creates a new typed flow entry with the given flow entry fe.
     *
     * @param fe flow entry
     */
    public static TypedStoredFlowEntry newTypedStoredFlowEntry(FlowEntry fe) {
        if (fe == null) {
            return null;
        }

        long life = fe.life();

        if (life >= LONG_POLL_INTERVAL) {
            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.LONG_FLOW);
        } else if (life >= MID_POLL_INTERVAL) {
            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.MID_FLOW);
        } else if (life >= CAL_AND_POLL_INTERVAL) {
            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW);
        } else if (life >= 0) {
            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW);
        } else { // life < 0
            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW);
        }
    }
}
