/*
 * Copyright 2015-present 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.group;

import org.onosproject.core.GroupId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;

import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Group bucket implementation. A group bucket is collection of
 * instructions that can be performed on a traffic flow. A select
 * Group can have one or more Buckets where traffic will be
 * processed by a single bucket in the group, based on device
 * specific selection algorithm (e.g. hash on some fields of the
 * incoming traffic flows or round robin) and hence can contains
 * optional weight field to define the weights among the buckets
 * in the group. A failover group bucket is associated with a
 * specific port or group that controls its liveness.
 */
public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketEntry {
    private final GroupDescription.Type type;
    private final TrafficTreatment treatment;
    private final short weight;
    private final PortNumber watchPort;
    private final GroupId watchGroup;
    private long packets;
    private long bytes;

    /**
     * Group bucket constructor with the parameters.
     *
     * @param type group bucket type
     * @param treatment traffic treatment associated with group bucket
     * @param weight optional weight associated with group bucket
     * @param watchPort port that determines the liveness of group bucket
     * @param watchGroup group that determines the liveness of group bucket
     */
    private DefaultGroupBucket(GroupDescription.Type type,
                               TrafficTreatment treatment,
                               short weight,
                               PortNumber watchPort,
                               GroupId watchGroup) {
        this.type = type;
        this.treatment = checkNotNull(treatment);
        this.weight = weight;
        this.watchPort = watchPort;
        this.watchGroup = watchGroup;
    }

    /**
     * Creates indirect group bucket.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return indirect group bucket object
     */
    public static GroupBucket createIndirectGroupBucket(
                                TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.INDIRECT,
                                      treatment,
                                      (short) -1,
                                      null,
                                      null);
    }

    /**
     * Creates select group bucket with weight as 1.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return select group bucket object
     */
    public static GroupBucket createSelectGroupBucket(
                                 TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
                                      treatment,
                                      (short) 1,
                                      null,
                                      null);
    }

    /**
     * Creates select group bucket with specified weight.
     *
     * @param treatment traffic treatment associated with group bucket
     * @param weight weight associated with group bucket
     * @return select group bucket object
     */
    public static GroupBucket createSelectGroupBucket(
                                 TrafficTreatment treatment,
                                 short weight) {
        if (weight == 0) {
            return null;
        }

        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
                                      treatment,
                                      weight,
                                      null,
                                      null);
    }

    /**
     * Creates failover group bucket with watchport or watchgroup.
     *
     * @param treatment traffic treatment associated with group bucket
     * @param watchPort port that determines the liveness of group bucket
     * @param watchGroup group that determines the liveness of group bucket
     * @return failover group bucket object
     */
    public static GroupBucket createFailoverGroupBucket(
                                 TrafficTreatment treatment,
                                 PortNumber watchPort,
                                 GroupId watchGroup) {
        checkArgument(((watchPort != null) || (watchGroup != null)));
        return new DefaultGroupBucket(GroupDescription.Type.FAILOVER,
                                      treatment,
                                      (short) -1,
                                      watchPort,
                                      watchGroup);
    }

    /**
     * Creates all group bucket.
     *
     * @param treatment traffic treatment associated with group bucket
     * @return all group bucket object
     */
    public static GroupBucket createAllGroupBucket(TrafficTreatment treatment) {
        return new DefaultGroupBucket(GroupDescription.Type.ALL,
                                      treatment,
                                      (short) -1,
                                      null,
                                      null);
    }

    @Override
    public GroupDescription.Type type() {
        return this.type;
    }

    /**
     * Returns list of Traffic instructions that are part of the bucket.
     *
     * @return TrafficTreatment Traffic instruction list
     */
    @Override
    public TrafficTreatment treatment() {
        return treatment;
    }

    /**
     * Returns weight of select group bucket.
     *
     * @return short weight associated with a bucket
     */
    @Override
    public short weight() {
        return weight;
    }

    /**
     * Returns port number used for liveness detection for a
     * failover bucket.
     *
     * @return PortNumber port number used for liveness detection
     */
    @Override
    public PortNumber watchPort() {
        return watchPort;
    }

    /**
     * Returns group identifier used for liveness detection for a
     * failover bucket.
     *
     * @return GroupId group identifier to be used for liveness detection
     */
    @Override
    public GroupId watchGroup() {
        return watchGroup;
    }

    /*
     * The type and treatment can change on a given bucket
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public int hashCode() {
        return Objects.hash(type, treatment);
    }

    /*
     * The priority and statistics can change on a given treatment and selector
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DefaultGroupBucket) {
            DefaultGroupBucket that = (DefaultGroupBucket) obj;
            List<Instruction> myInstructions = this.treatment.allInstructions();
            List<Instruction> theirInstructions = that.treatment.allInstructions();

            return Objects.equals(type, that.type) &&
                   myInstructions.containsAll(theirInstructions) &&
                   theirInstructions.containsAll(myInstructions);
        }
        return false;
    }

    @Override
    public boolean hasSameParameters(GroupBucket other) {
        return weight == other.weight() &&
               Objects.equals(watchPort, other.watchPort()) &&
               Objects.equals(watchGroup, other.watchGroup());
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("type", type)
                .add("treatment", treatment)
                .add("packets", packets)
                .add("bytes", bytes)
                .toString();
    }

    @Override
    public long packets() {
        return packets;
    }

    @Override
    public long bytes() {
        return bytes;
    }

    @Override
    public void setPackets(long packets) {
        this.packets = packets;
    }

    @Override
    public void setBytes(long bytes) {
        this.bytes = bytes;
    }
}
