/*
 * 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.flowclassifier;

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

import org.junit.Test;
import org.onlab.packet.IpPrefix;
import org.onosproject.vtnrsc.TenantId;
import org.onosproject.vtnrsc.DefaultFlowClassifier;
import org.onosproject.vtnrsc.FlowClassifierId;
import org.onosproject.vtnrsc.VirtualPortId;
import org.onosproject.vtnrsc.FlowClassifier;

import com.google.common.testing.EqualsTester;

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