/*
 * 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.net.PortNumber;
import org.onosproject.net.flow.instructions.Instructions;
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.hamcrest.Matchers.not;
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 TREATMENT1 =
            new IntentTestsMocks.MockTreatment(
                    Instructions.createOutput(PortNumber.portNumber(1)));
    private static final IntentTestsMocks.MockTreatment TREATMENT2 =
            new IntentTestsMocks.MockTreatment(
                    Instructions.createOutput(PortNumber.portNumber(2)));

    final FlowRule flowRule1 = new IntentTestsMocks.MockFlowRule(1);
    final FlowRule sameAsFlowRule1 = new IntentTestsMocks.MockFlowRule(1);
    final FlowRule flowRule2 = new IntentTestsMocks.MockFlowRule(2);
    final DefaultFlowRule defaultFlowRule1 = new DefaultFlowRule(flowRule1);
    final DefaultFlowRule sameAsDefaultFlowRule1 = new DefaultFlowRule(sameAsFlowRule1);
    final DefaultFlowRule defaultFlowRule2 = new DefaultFlowRule(flowRule2);

    /**
     * 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)
                .addEqualityGroup(defaultFlowRule2)
                .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()));
    }

    /**
     * Tests creation of a DefaultFlowRule using a FlowId constructor.
     */
    @Test
    public void testCreationWithFlowId() {
        final DefaultFlowRule rule =
                new DefaultFlowRule(did("1"), SELECTOR,
                TREATMENT1, 22, 33,
                44, false);
        assertThat(rule.deviceId(), is(did("1")));
        assertThat(rule.id().value(), is(33L));
        assertThat(rule.isPermanent(), is(false));
        assertThat(rule.priority(), is(22));
        assertThat(rule.selector(), is(SELECTOR));
        assertThat(rule.treatment(), is(TREATMENT1));
        assertThat(rule.timeout(), is(44));
    }

    /**
     * Tests the creation of a DefaultFlowRule using an AppId constructor.
     */
    @Test
    public void testCreationWithAppId() {
        final DefaultFlowRule rule =
                new DefaultFlowRule(did("1"), SELECTOR,
                TREATMENT1, 22, APP_ID,
                        44, false);
        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(TREATMENT1));
        assertThat(rule.timeout(), is(44));
    }

    /**
     * Tests equality that factors in TrafficTreatment through the flowId.
     */
    @Test
    public void testActionEquals() {
        final DefaultFlowRule rule1 = new DefaultFlowRule(did("1"), SELECTOR,
                TREATMENT1, 22, APP_ID, 44, false);
        final DefaultFlowRule rule2 = new DefaultFlowRule(did("1"), SELECTOR,
                TREATMENT2, 22, APP_ID, 44, false);
        assertThat(rule1, not(rule2));
    }
}
