/*
 * Copyright 2016-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.incubator.net.virtual.impl;

import com.google.common.collect.Iterators;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.osgi.TestServiceDirectory;
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualHost;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Host;
import org.onosproject.net.NetTestTools;
import org.onosproject.net.TestDeviceParams;
import org.onosproject.net.host.HostService;
import org.onosproject.net.intent.FakeIntentManager;
import org.onosproject.net.intent.TestableIntentService;
import org.onosproject.store.service.TestStorageService;

import java.util.Collection;
import java.util.Iterator;

import static org.junit.Assert.*;

/**
 * Junit tests for VirtualNetworkHostService.
 */
public class VirtualNetworkHostManagerTest extends TestDeviceParams {
    private final String tenantIdValue1 = "TENANT_ID1";

    private VirtualNetworkManager manager;
    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
    private TestableIntentService intentService = new FakeIntentManager();
    private TestServiceDirectory testDirectory;

    @Before
    public void setUp() throws Exception {
        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();

        CoreService coreService = new TestCoreService();
        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
        virtualNetworkManagerStore.activate();

        manager = new VirtualNetworkManager();
        manager.store = virtualNetworkManagerStore;
        manager.intentService = intentService;
        manager.coreService = coreService;
        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());

        testDirectory = new TestServiceDirectory();
        TestUtils.setField(manager, "serviceDirectory", testDirectory);

        manager.activate();
    }

    @After
    public void tearDown() {
        virtualNetworkManagerStore.deactivate();
        manager.deactivate();
        NetTestTools.injectEventDispatcher(manager, null);
    }

    /**
     * Sets up a virtual network with hosts.
     *
     * @return virtual network
     */
    private VirtualNetwork setupVnet() {
        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
        manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
        manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
        return virtualNetwork;
    }

    /**
     * Sets up a virtual network with no hosts.
     *
     * @return virtual network
     */
    private VirtualNetwork setupEmptyVnet() {
        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
        return manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
    }

    /**
     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
     * on a non-empty virtual network.
     */
    @Test
    public void testGetHostsOnNonEmptyVnet() {
        VirtualNetwork virtualNetwork = setupEmptyVnet();
        VirtualHost vhost1 = manager.createVirtualHost(virtualNetwork.id(), HID1, MAC1, VLAN1, LOC1, IPSET1);
        VirtualHost vhost2 = manager.createVirtualHost(virtualNetwork.id(), HID2, MAC2, VLAN2, LOC2, IPSET2);
        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);

        // test the getHosts() and getHostCount() methods
        Iterator<Host> itHosts = hostService.getHosts().iterator();
        assertEquals("The host set size did not match.", 2, Iterators.size(itHosts));
        assertEquals("The host count did not match.", 2, hostService.getHostCount());

        // test the getHost() method
        Host testHost = hostService.getHost(HID2);
        assertEquals("The expected host did not match.", vhost2, testHost);

        // test the getHostsByVlan(...) method
        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
        assertEquals("The host set size did not match.", 1, collHost.size());
        assertTrue("The host did not match.", collHost.contains(vhost1));

        // test the getHostsByMac(...) method
        collHost = hostService.getHostsByMac(MAC2);
        assertEquals("The host set size did not match.", 1, collHost.size());
        assertTrue("The host did not match.", collHost.contains(vhost2));

        // test the getHostsByIp(...) method
        collHost = hostService.getHostsByIp(IP1);
        assertEquals("The host set size did not match.", 2, collHost.size());
        collHost = hostService.getHostsByIp(IP2);
        assertEquals("The host set size did not match.", 1, collHost.size());
        assertTrue("The host did not match.", collHost.contains(vhost1));

        // test the getConnectedHosts(ConnectPoint) method
        collHost = hostService.getConnectedHosts(LOC1);
        assertEquals("The host set size did not match.", 1, collHost.size());
        assertTrue("The host did not match.", collHost.contains(vhost1));

        // test the getConnectedHosts(DeviceId) method
        collHost = hostService.getConnectedHosts(DID2);
        assertEquals("The host set size did not match.", 1, collHost.size());
        assertTrue("The host did not match.", collHost.contains(vhost2));
    }

    /**
     * Tests the getHosts(), getHost(), getHostsByXX(), getConnectedHosts() methods
     * on an empty virtual network.
     */
    @Test
    public void testGetHostsOnEmptyVnet() {
        VirtualNetwork virtualNetwork = setupEmptyVnet();
        HostService hostService = manager.get(virtualNetwork.id(), HostService.class);

        // test the getHosts() and getHostCount() methods
        Iterator<Host> itHosts = hostService.getHosts().iterator();
        assertEquals("The host set size did not match.", 0, Iterators.size(itHosts));
        assertEquals("The host count did not match.", 0, hostService.getHostCount());

        // test the getHost() method
        Host testHost = hostService.getHost(HID2);
        assertNull("The host should be null.", testHost);

        // test the getHostsByVlan(...) method
        Collection<Host> collHost = hostService.getHostsByVlan(VLAN1);
        assertEquals("The host set size did not match.", 0, collHost.size());

        // test the getHostsByMac(...) method
        collHost = hostService.getHostsByMac(MAC2);
        assertEquals("The host set size did not match.", 0, collHost.size());

        // test the getHostsByIp(...) method
        collHost = hostService.getHostsByIp(IP1);
        assertEquals("The host set size did not match.", 0, collHost.size());

        // test the getConnectedHosts(ConnectPoint) method
        collHost = hostService.getConnectedHosts(LOC1);
        assertEquals("The host set size did not match.", 0, collHost.size());

        // test the getConnectedHosts(DeviceId) method
        collHost = hostService.getConnectedHosts(DID2);
        assertEquals("The host set size did not match.", 0, collHost.size());
    }

    /**
     * Tests querying for a host using a null host identifier.
     */
    @Test(expected = NullPointerException.class)
    public void testGetHostByNullId() {
        VirtualNetwork vnet = setupEmptyVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getHost(null);
    }

    /**
     * Tests querying for hosts with null mac.
     */
    @Test(expected = NullPointerException.class)
    public void testGetHostsByNullMac() {
        VirtualNetwork vnet = setupEmptyVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getHostsByMac(null);
    }

    /**
     * Tests querying for hosts with null vlan.
     */
    @Test(expected = NullPointerException.class)
    public void testGetHostsByNullVlan() {
        VirtualNetwork vnet = setupEmptyVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getHostsByVlan(null);
    }

    /**
     * Tests querying for hosts with null ip.
     */
    @Test(expected = NullPointerException.class)
    public void testGetHostsByNullIp() {
        VirtualNetwork vnet = setupVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getHostsByIp(null);
    }

    /**
     * Tests querying for connected hosts with null host location (connect point).
     */
    @Test(expected = NullPointerException.class)
    public void testGetConnectedHostsByNullLoc() {
        VirtualNetwork vnet = setupEmptyVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getConnectedHosts((ConnectPoint) null);
    }

    /**
     * Tests querying for connected hosts with null device id.
     */
    @Test(expected = NullPointerException.class)
    public void testGetConnectedHostsByNullDeviceId() {
        VirtualNetwork vnet = setupVnet();
        HostService hostService = manager.get(vnet.id(), HostService.class);

        hostService.getConnectedHosts((DeviceId) null);
    }

}
