/*
 * Copyright 2015-present 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.vtnrsc;

import org.junit.Test;
import org.onlab.packet.IpPrefix;

import com.google.common.testing.EqualsTester;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;

/**
 * Unit tests for DefaultFlowClassifier class.
 */
public class DefaultFlowClassifierTest {
    /**
     * Checks that the DefaultFlowClassifier class is immutable.
     */
    @Test
    public void testImmutability() {
        assertThatClassIsImmutable(DefaultFlowClassifier.class);
    }

    /**
     * Checks the operation of equals() methods.
     */
    @Test
    public void testEquals() {
        // Create same two flow classifier objects.
        final String name = "FlowClassifier1";
        final String description = "FlowClassifier1";
        final String ethType = "IPv4";
        final String protocol = "tcp";
        final int minSrcPortRange = 5;
        final int maxSrcPortRange = 10;
        final int minDstPortRange = 5;
        final int maxDstPortRange = 10;
        final FlowClassifierId flowClassifierId = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
        final TenantId tenantId = TenantId.tenantId("1");
        final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
        final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0");
        final VirtualPortId virtualSrcPort = VirtualPortId.portId("1");
        final VirtualPortId virtualDstPort = VirtualPortId.portId("2");

        DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
        final FlowClassifier flowClassifier1 = flowClassifierBuilder.setFlowClassifierId(flowClassifierId)
                .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType)
                .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
                .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
                .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();

        flowClassifierBuilder = new DefaultFlowClassifier.Builder();
        final FlowClassifier sameAsFlowClassifier1 = flowClassifierBuilder.setFlowClassifierId(flowClassifierId)
                .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType)
                .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
                .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
                .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();

        // Create different classifier object.
        final String name2 = "FlowClassifier2";
        final String description2 = "FlowClassifier2";
        final String ethType2 = "IPv6";
        final String protocol2 = "udp";
        final int minSrcPortRange2 = 5;
        final int maxSrcPortRange2 = 10;
        final int minDstPortRange2 = 5;
        final int maxDstPortRange2 = 10;
        final FlowClassifierId flowClassifierId2 = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
        final TenantId tenantId2 = TenantId.tenantId("2");
        final IpPrefix srcIpPrefix2 = IpPrefix.valueOf("0.0.0.0/0");
        final IpPrefix dstIpPrefix2 = IpPrefix.valueOf("10.10.10.10/0");
        final VirtualPortId virtualSrcPort2 = VirtualPortId.portId("3");
        final VirtualPortId virtualDstPort2 = VirtualPortId.portId("4");

        DefaultFlowClassifier.Builder flowClassifierBuilder3 = new DefaultFlowClassifier.Builder();
        final FlowClassifier flowClassifier2 = flowClassifierBuilder3.setFlowClassifierId(flowClassifierId2)
                .setTenantId(tenantId2).setName(name2).setDescription(description2).setEtherType(ethType2)
                .setProtocol(protocol2).setMinSrcPortRange(minSrcPortRange2).setMaxSrcPortRange(maxSrcPortRange2)
                .setMinDstPortRange(minDstPortRange2).setMaxDstPortRange(maxDstPortRange2).setSrcIpPrefix(srcIpPrefix2)
                .setDstIpPrefix(dstIpPrefix2).setSrcPort(virtualSrcPort2).setDstPort(virtualDstPort2).build();

        new EqualsTester().addEqualityGroup(flowClassifier1, sameAsFlowClassifier1).addEqualityGroup(flowClassifier2)
                .testEquals();
    }

    /**
     * Checks the construction of a DefaultFlowClassifier object.
     */
    @Test
    public void testConstruction() {
        final String name = "FlowClassifier";
        final String description = "FlowClassifier";
        final String ethType = "IPv4";
        final String protocol = "tcp";
        final int minSrcPortRange = 5;
        final int maxSrcPortRange = 10;
        final int minDstPortRange = 5;
        final int maxDstPortRange = 10;
        final FlowClassifierId flowClassifierId = FlowClassifierId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae");
        final TenantId tenantId = TenantId.tenantId("1");
        final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0");
        final IpPrefix dstIpPrefix = IpPrefix.valueOf("10.10.10.10/0");
        final VirtualPortId virtualSrcPort = VirtualPortId.portId("1");
        final VirtualPortId virtualDstPort = VirtualPortId.portId("2");

        DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder();
        final FlowClassifier flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId)
                .setTenantId(tenantId).setName(name).setDescription(description).setEtherType(ethType)
                .setProtocol(protocol).setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange)
                .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix)
                .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build();

        assertThat(flowClassifierId, is(flowClassifier.flowClassifierId()));
        assertThat(tenantId, is(flowClassifier.tenantId()));
        assertThat(name, is(flowClassifier.name()));
        assertThat(description, is(flowClassifier.description()));
        assertThat(ethType, is(flowClassifier.etherType()));
        assertThat(protocol, is(flowClassifier.protocol()));
        assertThat(minSrcPortRange, is(flowClassifier.minSrcPortRange()));
        assertThat(maxSrcPortRange, is(flowClassifier.maxSrcPortRange()));
        assertThat(minDstPortRange, is(flowClassifier.minDstPortRange()));
        assertThat(maxDstPortRange, is(flowClassifier.maxDstPortRange()));
        assertThat(srcIpPrefix, is(flowClassifier.srcIpPrefix()));
        assertThat(dstIpPrefix, is(flowClassifier.dstIpPrefix()));
        assertThat(virtualSrcPort, is(flowClassifier.srcPort()));
        assertThat(virtualDstPort, is(flowClassifier.dstPort()));
    }
}
