/*
 * 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 java.util.concurrent.TimeUnit;

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

import com.google.common.testing.EqualsTester;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.is;
import static org.onosproject.net.NetTestTools.did;

/**
 * Unit tests for the DefaultFlowEntry class.
 */
public class DefaultFlowEntryTest {
    private static final IntentTestsMocks.MockSelector SELECTOR =
            new IntentTestsMocks.MockSelector();
    private static final IntentTestsMocks.MockTreatment TREATMENT =
            new IntentTestsMocks.MockTreatment();

    private static DefaultFlowEntry makeFlowEntry(int uniqueValue) {
        return new DefaultFlowEntry(did("id" + Integer.toString(uniqueValue)),
                SELECTOR,
                TREATMENT,
                uniqueValue,
                FlowEntry.FlowEntryState.ADDED,
                uniqueValue,
                uniqueValue,
                uniqueValue,
                uniqueValue,
                uniqueValue);
    }

    final DefaultFlowEntry defaultFlowEntry1 = makeFlowEntry(1);
    final DefaultFlowEntry sameAsDefaultFlowEntry1 = makeFlowEntry(1);
    final DefaultFlowEntry defaultFlowEntry2 = makeFlowEntry(2);

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

    /**
     * Tests the construction of a default flow entry from a device id.
     */
    @Test
    public void testDeviceBasedObject() {
        assertThat(defaultFlowEntry1.deviceId(), is(did("id1")));
        assertThat(defaultFlowEntry1.selector(), is(SELECTOR));
        assertThat(defaultFlowEntry1.treatment(), is(TREATMENT));
        assertThat(defaultFlowEntry1.timeout(), is(1));
        assertThat(defaultFlowEntry1.life(), is(1L));
        assertThat(defaultFlowEntry1.packets(), is(1L));
        assertThat(defaultFlowEntry1.bytes(), is(1L));
        assertThat(defaultFlowEntry1.state(), is(FlowEntry.FlowEntryState.ADDED));
        assertThat(defaultFlowEntry1.lastSeen(),
                   greaterThan(System.currentTimeMillis() -
                           TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS)));
    }

    /**
     * Tests the setters on a default flow entry object.
     */
    @Test
    public void testSetters() {
        final DefaultFlowEntry entry = makeFlowEntry(1);

        entry.setLastSeen();
        entry.setState(FlowEntry.FlowEntryState.PENDING_REMOVE);
        entry.setPackets(11);
        entry.setBytes(22);
        entry.setLife(33);

        assertThat(entry.deviceId(), is(did("id1")));
        assertThat(entry.selector(), is(SELECTOR));
        assertThat(entry.treatment(), is(TREATMENT));
        assertThat(entry.timeout(), is(1));
        assertThat(entry.life(), is(33L));
        assertThat(entry.packets(), is(11L));
        assertThat(entry.bytes(), is(22L));
        assertThat(entry.state(), is(FlowEntry.FlowEntryState.PENDING_REMOVE));
        assertThat(entry.lastSeen(),
                greaterThan(System.currentTimeMillis() -
                        TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS)));
    }

    /**
     * Tests a default flow rule built for an error.
     */
    @Test
    public void testErrorObject() {
        final DefaultFlowEntry errorEntry =
                new DefaultFlowEntry(new IntentTestsMocks.MockFlowRule(1),
                                     111,
                                     222);
        assertThat(errorEntry.errType(), is(111));
        assertThat(errorEntry.errCode(), is(222));
        assertThat(errorEntry.state(), is(FlowEntry.FlowEntryState.FAILED));
        assertThat(errorEntry.lastSeen(),
                greaterThan(System.currentTimeMillis() -
                        TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS)));
    }

    /**
     * Tests a default flow entry constructed from a flow rule.
     */
    @Test
    public void testFlowBasedObject() {
        final DefaultFlowEntry entry =
                new DefaultFlowEntry(new IntentTestsMocks.MockFlowRule(1));
        assertThat(entry.priority(), is(1));
        assertThat(entry.appId(), is((short) 0));
        assertThat(entry.lastSeen(),
                greaterThan(System.currentTimeMillis() -
                        TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS)));
    }

    /**
     * Tests a default flow entry constructed from a flow rule plus extra
     * parameters.
     */
    @Test
    public void testFlowBasedObjectWithParameters() {
        final DefaultFlowEntry entry =
                new DefaultFlowEntry(new IntentTestsMocks.MockFlowRule(33),
                        FlowEntry.FlowEntryState.REMOVED,
                        101, 102, 103);
        assertThat(entry.state(), is(FlowEntry.FlowEntryState.REMOVED));
        assertThat(entry.life(), is(101L));
        assertThat(entry.packets(), is(102L));
        assertThat(entry.bytes(), is(103L));
        assertThat(entry.lastSeen(),
                greaterThan(System.currentTimeMillis() -
                        TimeUnit.MILLISECONDS.convert(1, TimeUnit.SECONDS)));
    }
}
