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