/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 static com.google.common.base.MoreObjects.toStringHelper;

import java.util.Objects;

import org.onosproject.core.GroupId;
import org.onosproject.net.DeviceId;

/**
 * ONOS implementation of default group that is stored in the system.
 */
public class DefaultGroup extends DefaultGroupDescription
    implements Group, StoredGroupEntry {

    private GroupState state;
    private boolean isGroupStateAddedFirstTime;
    private long life;
    private long packets;
    private long bytes;
    private long referenceCount;
    private GroupId id;
    private int age;
    private int failedRetryCount;

    /**
     * Initializes default values.
     *
     * @param newId group id for new group
     */
    private void initialize(GroupId newId) {
        id = newId;
        state = GroupState.PENDING_ADD;
        life = 0;
        packets = 0;
        bytes = 0;
        referenceCount = 0;
        age = 0;
        failedRetryCount = 0;
    }

    /**
     * Default group object constructor with the parameters.
     *
     * @param id group identifier
     * @param groupDesc group description parameters
     */
    public DefaultGroup(GroupId id, GroupDescription groupDesc) {
        super(groupDesc);
        initialize(id);
    }

    /**
     * Default group object constructor with the available information
     * from data plane.
     *
     * @param id group identifier
     * @param deviceId device identifier
     * @param type type of the group
     * @param buckets immutable list of group bucket
     */
    public DefaultGroup(GroupId id,
                        DeviceId deviceId,
                        GroupDescription.Type type,
                        GroupBuckets buckets) {
        super(deviceId, type, buckets);
        initialize(id);
    }

    /**
     * Returns group identifier associated with a group object.
     *
     * @return GroupId Group Identifier
     */
    @Override
    public GroupId id() {
        return this.id;
    }

    /**
     * Returns current state of a group object.
     *
     * @return GroupState Group State
     */
    @Override
    public GroupState state() {
        return this.state;
    }

    /**
     * Returns the number of milliseconds this group has been alive.
     *
     * @return number of millis
     */
    @Override
    public long life() {
        return this.life;
    }

    /**
     * Returns the number of packets processed by this group.
     *
     * @return number of packets
     */
    @Override
    public long packets() {
        return this.packets;
    }

    /**
     * Returns the number of bytes processed by this group.
     *
     * @return number of bytes
     */
    @Override
    public long bytes() {
        return this.bytes;
    }

    @Override
    public int age() {
        return age;
    }

    @Override
    public int failedRetryCount() {
        return failedRetryCount;
    }

    /**
     * Sets the new state for this entry.
     *
     * @param newState new group entry state.
     */
    @Override
    public void setState(Group.GroupState newState) {
        this.state = newState;
    }

    /**
     * Sets how long this entry has been entered in the system.
     *
     * @param life epoch time
     */
    @Override
    public void setLife(long life) {
        this.life = life;
    }

    /**
     * Sets number of packets processed by this group entry.
     *
     * @param packets a long value
     */
    @Override
    public void setPackets(long packets) {
        this.packets = packets;
    }

    /**
     * Sets number of bytes processed by this group entry.
     *
     * @param bytes a long value
     */
    @Override
    public void setBytes(long bytes) {
        this.bytes = bytes;
    }

    @Override
    public void setReferenceCount(long referenceCount) {
        this.referenceCount = referenceCount;
        if (referenceCount == 0) {
            age++;
        } else {
            age = 0;
        }
    }

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

    @Override
    public void incrFailedRetryCount() {
        failedRetryCount++;
    }

    @Override
    public void setFailedRetryCount(int failedRetryCount) {
        this.failedRetryCount = failedRetryCount;
    }

    /*
     * The deviceId, type and buckets are used for hash.
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), id);
    }

    /*
     * The deviceId, groupId, type and buckets should be same.
     *
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
       if (obj instanceof DefaultGroup) {
            DefaultGroup that = (DefaultGroup) obj;
            return super.equals(obj) &&
                    Objects.equals(id, that.id);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("description", super.toString())
                .add("groupid", id)
                .add("state", state)
                .add("age", age)
                .toString();
    }

    @Override
    public void setIsGroupStateAddedFirstTime(boolean isGroupStateAddedFirstTime) {
        this.isGroupStateAddedFirstTime = isGroupStateAddedFirstTime;
    }

    @Override
    public boolean isGroupStateAddedFirstTime() {
        return isGroupStateAddedFirstTime;
    }
}
