/*
 * Copyright 2014 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.flow;

import org.junit.Test;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.net.intent.IntentTestsMocks;

import com.google.common.testing.EqualsTester;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
import static org.onosproject.net.NetTestTools.APP_ID;
import static org.onosproject.net.NetTestTools.did;

/**
 * Unit tests for the default flow rule class.
 */
public class DefaultFlowRuleTest {
    private static final IntentTestsMocks.MockSelector SELECTOR =
            new IntentTestsMocks.MockSelector();
    private static final IntentTestsMocks.MockTreatment TREATMENT =
            new IntentTestsMocks.MockTreatment();

    private static byte[] b = new byte[3];
    private static FlowRuleExtPayLoad payLoad = FlowRuleExtPayLoad.flowRuleExtPayLoad(b);
    final FlowRule flowRule1 = new IntentTestsMocks.MockFlowRule(1, payLoad);
    final FlowRule sameAsFlowRule1 = new IntentTestsMocks.MockFlowRule(1, payLoad);
    final DefaultFlowRule defaultFlowRule1 = new DefaultFlowRule(flowRule1);
    final DefaultFlowRule sameAsDefaultFlowRule1 = new DefaultFlowRule(sameAsFlowRule1);

    /**
     * Checks that the DefaultFlowRule class is immutable but can be inherited
     * from.
     */
    @Test
    public void testImmutability() {
        assertThatClassIsImmutableBaseClass(DefaultFlowRule.class);
    }

    /**
     * Tests the equals, hashCode and toString methods using Guava EqualsTester.
     */
    @Test
    public void testEquals() {
        new EqualsTester()
                .addEqualityGroup(defaultFlowRule1, sameAsDefaultFlowRule1)
                .testEquals();
    }

    /**
     * Tests creation of a DefaultFlowRule using a FlowRule constructor.
     */
    @Test
    public void testCreationFromFlowRule() {
        assertThat(defaultFlowRule1.deviceId(), is(flowRule1.deviceId()));
        assertThat(defaultFlowRule1.appId(), is(flowRule1.appId()));
        assertThat(defaultFlowRule1.id(), is(flowRule1.id()));
        assertThat(defaultFlowRule1.isPermanent(), is(flowRule1.isPermanent()));
        assertThat(defaultFlowRule1.priority(), is(flowRule1.priority()));
        assertThat(defaultFlowRule1.selector(), is(flowRule1.selector()));
        assertThat(defaultFlowRule1.treatment(), is(flowRule1.treatment()));
        assertThat(defaultFlowRule1.timeout(), is(flowRule1.timeout()));
        assertThat(defaultFlowRule1.payLoad(), is(flowRule1.payLoad()));
    }

    /**
     * Tests creation of a DefaultFlowRule using a FlowId constructor.
     */

    @Test
    public void testCreationWithFlowId() {
        final FlowRule rule =
                DefaultFlowRule.builder()
                .forDevice(did("1"))
                .withSelector(SELECTOR)
                .withTreatment(TREATMENT)
                .withPriority(22)
                .makeTemporary(44)
                .fromApp(APP_ID)
                .build();

        assertThat(rule.deviceId(), is(did("1")));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.priority(), is(22));
        assertThat(rule.selector(), is(SELECTOR));
        assertThat(rule.treatment(), is(TREATMENT));
        assertThat(rule.timeout(), is(44));
    }


    /**
     * Tests creation of a DefaultFlowRule using a PayLoad constructor.
     */
    @Test
    public void testCreationWithPayLoadByFlowTable() {
        final DefaultFlowRule rule =
                new DefaultFlowRule(did("1"), null,
                        null, 22, APP_ID,
                44, false, payLoad);
        assertThat(rule.deviceId(), is(did("1")));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.priority(), is(22));
        assertThat(rule.timeout(), is(44));
        assertThat(defaultFlowRule1.payLoad(), is(payLoad));
    }

    /**
     * Tests creation of a DefaultFlowRule using a PayLoad constructor.
     */
    @Test
    public void testCreationWithPayLoadByGroupTable() {
        final DefaultFlowRule rule =
                new DefaultFlowRule(did("1"), null,
                        null, 22, APP_ID, new DefaultGroupId(0),
                44, false, payLoad);
        assertThat(rule.deviceId(), is(did("1")));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.priority(), is(22));
        assertThat(rule.timeout(), is(44));
        assertThat(rule.groupId(), is(new DefaultGroupId(0)));
        assertThat(defaultFlowRule1.payLoad(), is(payLoad));
    }
    /**
     * Tests the creation of a DefaultFlowRule using an AppId constructor.
     */
    @Test
    public void testCreationWithAppId() {
        final FlowRule rule =
                DefaultFlowRule.builder()
                        .forDevice(did("1"))
                        .withSelector(SELECTOR)
                        .withTreatment(TREATMENT)
                        .withPriority(22)
                        .fromApp(APP_ID)
                        .makeTemporary(44)
                        .build();

        assertThat(rule.deviceId(), is(did("1")));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.priority(), is(22));
        assertThat(rule.selector(), is(SELECTOR));
        assertThat(rule.treatment(), is(TREATMENT));
        assertThat(rule.timeout(), is(44));
    }
}
