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

import org.junit.Test;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.core.GroupId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;

import com.google.common.testing.EqualsTester;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.onosproject.net.group.GroupDescription.Type.FAILOVER;
import static org.onosproject.net.group.GroupDescription.Type.INDIRECT;
import static org.onosproject.net.group.GroupDescription.Type.SELECT;

/**
 * Unit tests for the group bucket class.
 */
public class GroupBucketTest {

    private final GroupId groupId = new DefaultGroupId(7);
    private final GroupId nullGroup = null;

    private final PortNumber nullPort = null;

    private final TrafficTreatment treatment =
            DefaultTrafficTreatment.emptyTreatment();
    private final GroupBucket selectGroupBucket =
            DefaultGroupBucket.createSelectGroupBucket(treatment);
    private final GroupBucket sameAsSelectGroupBucket =
            DefaultGroupBucket.createSelectGroupBucket(treatment);
    private final GroupBucket failoverGroupBucket =
            DefaultGroupBucket.createFailoverGroupBucket(treatment,
                    PortNumber.IN_PORT, groupId);
    private final GroupBucket indirectGroupBucket =
            DefaultGroupBucket.createIndirectGroupBucket(treatment);
    private final GroupBucket selectGroupBucketWithWeight =
            DefaultGroupBucket.createSelectGroupBucket(treatment, (short) 5);


    /**
     * Tests for proper operation of equals(), hashCode() and toString() methods.
     */
    @Test
    public void checkEquals() {
        new EqualsTester()
                .addEqualityGroup(selectGroupBucket,
                        sameAsSelectGroupBucket,
                        selectGroupBucketWithWeight)
                .addEqualityGroup(failoverGroupBucket)
                .addEqualityGroup(indirectGroupBucket)
                .testEquals();
    }

    private void checkValues(GroupBucket bucket, GroupDescription.Type type,
                             long bytes, long packets, short weight,
                             GroupId groupId, PortNumber portNumber) {
        assertThat(bucket.type(), is(type));
        assertThat(bucket.bytes(), is(bytes));
        assertThat(bucket.packets(), is(packets));
        assertThat(bucket.treatment(), is(treatment));
        assertThat(bucket.weight(), is(weight));
        assertThat(bucket.watchGroup(), is(groupId));
        assertThat(bucket.watchPort(), is(portNumber));
    }

    /**
     * Checks that construction of a select group was correct.
     */
    @Test
    public void checkSelectGroup() {
        // Casting needed because only the store accesses the set methods.
        ((DefaultGroupBucket) selectGroupBucket).setBytes(4);
        ((DefaultGroupBucket) selectGroupBucket).setPackets(44);

        checkValues(selectGroupBucket, SELECT, 4L, 44L, (short) 1,
                nullGroup, nullPort);
    }

    /**
     * Checks that construction of a select group with a weight was correct.
     */
    @Test
    public void checkSelectGroupWithPriority() {
        checkValues(selectGroupBucketWithWeight, SELECT, 0L, 0L, (short) 5,
                nullGroup, nullPort);
    }

    /**
     * Checks that construction of an indirect group was correct.
     */
    @Test
    public void checkFailoverGroup() {
        checkValues(failoverGroupBucket, FAILOVER, 0L, 0L, (short) -1,
                groupId, PortNumber.IN_PORT);
    }
    /**
     * Checks that construction of an indirect group was correct.
     */
    @Test
    public void checkIndirectGroup() {
        checkValues(indirectGroupBucket, INDIRECT, 0L, 0L, (short) -1,
                nullGroup, nullPort);
    }

    /**
     * Checks that a weight of 0 results in no group getting created.
     */
    @Test
    public void checkZeroWeight() {
        GroupBucket bucket =
                DefaultGroupBucket.createSelectGroupBucket(treatment, (short) 0);
        assertThat(bucket, nullValue());
    }
}
