/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.openstacknetworking.impl;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.Event;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.onosproject.store.service.TestStorageService;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Subnet;
import org.openstack4j.openstack.networking.domain.NeutronNetwork;
import org.openstack4j.openstack.networking.domain.NeutronPort;
import org.openstack4j.openstack.networking.domain.NeutronSubnet;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_CREATED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_REMOVED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_NETWORK_UPDATED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_CREATED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_REMOVED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_UPDATED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_CREATED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_REMOVED;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_SUBNET_UPDATED;
import static org.onosproject.openstacknode.api.NodeState.COMPLETE;

/**
 * Unit tests for OpenStack network manager.
 */
public class OpenstackNetworkManagerTest {

    private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");

    private static final String UNKNOWN_ID = "unknown_id";
    private static final String UPDATED_NAME = "updated_name";

    private static final String NETWORK_ID = "network_id";
    private static final String NETWORK_NAME = "network_name";
    private static final Network NETWORK = NeutronNetwork.builder()
            .name(NETWORK_NAME)
            .build();
    private static final Network NETWORK_COPY = NeutronNetwork.builder()
            .name("network")
            .build();

    private static final String SUBNET_ID = "subnet_id";
    private static final Subnet SUBNET = NeutronSubnet.builder()
            .networkId(NETWORK_ID)
            .cidr("192.168.0.0/24")
            .build();
    private static final Subnet SUBNET_COPY = NeutronSubnet.builder()
            .networkId(NETWORK_ID)
            .cidr("192.168.0.0/24")
            .build();

    private static final String PORT_ID = "port_id";
    private static final Port PORT = NeutronPort.builder()
            .networkId(NETWORK_ID)
            .fixedIp("192.168.0.1", SUBNET_ID)
            .build();
    private static final Port PORT_COPY = NeutronPort.builder()
            .networkId(NETWORK_ID)
            .fixedIp("192.168.0.1", SUBNET_ID)
            .build();

    private final TestOpenstackNetworkListener testListener = new TestOpenstackNetworkListener();

    private OpenstackNetworkManager target;
    private DistributedOpenstackNetworkStore osNetworkStore;

    @Before
    public void setUp() throws Exception {
        NETWORK.setId(NETWORK_ID);
        NETWORK_COPY.setId(NETWORK_ID);
        SUBNET.setId(SUBNET_ID);
        SUBNET_COPY.setId(SUBNET_ID);
        PORT.setId(PORT_ID);
        PORT_COPY.setId(PORT_ID);

        osNetworkStore = new DistributedOpenstackNetworkStore();
        TestUtils.setField(osNetworkStore, "coreService", new TestCoreService());
        TestUtils.setField(osNetworkStore, "storageService", new TestStorageService());
        TestUtils.setField(osNetworkStore, "eventExecutor", MoreExecutors.newDirectExecutorService());
        osNetworkStore.activate();

        target = new OpenstackNetworkManager();
        TestUtils.setField(target, "coreService", new TestCoreService());
        TestUtils.setField(target, "packetService", new PacketServiceAdapter());
        TestUtils.setField(target, "deviceService", new DeviceServiceAdapter());
        TestUtils.setField(target, "storageService", new TestStorageService());
        TestUtils.setField(target, "clusterService", new ClusterServiceAdapter());
        TestUtils.setField(target, "openstacknodeService", new TestOpenstackNodeManager());
        target.osNetworkStore = osNetworkStore;
        target.addListener(testListener);
        target.activate();
    }

    @After
    public void tearDown() {
        target.removeListener(testListener);
        osNetworkStore.deactivate();
        target.deactivate();
        osNetworkStore = null;
        target = null;
    }

    /**
     * Tests if getting all networks returns the correct set of networks.
     */
    @Test
    public void testGetNetworks() {
        createBasicNetworks();
        assertEquals("Number of network did not match", 1, target.networks().size());
    }

    /**
     * Tests if getting a network with ID returns the correct network.
     */
    @Test
    public void testGetNetworkById() {
        createBasicNetworks();
        assertTrue("Network did not match", target.network(NETWORK_ID) != null);
        assertTrue("Network did not match", target.network(UNKNOWN_ID) == null);
    }

    /**
     * Tests creating and removing a network, and checks if it triggers proper events.
     */
    @Test
    public void testCreateAndRemoveNetwork() {
        target.createNetwork(NETWORK);
        assertEquals("Number of networks did not match", 1, target.networks().size());
        assertTrue("Network was not created", target.network(NETWORK_ID) != null);

        target.removeNetwork(NETWORK_ID);
        assertEquals("Number of networks did not match", 0, target.networks().size());
        assertTrue("Network was not removed", target.network(NETWORK_ID) == null);

        validateEvents(OPENSTACK_NETWORK_CREATED, OPENSTACK_NETWORK_REMOVED);
    }

    /**
     * Tests updating a network, and checks if it triggers proper events.
     */
    @Test
    public void testCreateAndUpdateNetwork() {
        target.createNetwork(NETWORK);
        assertEquals("Number of networks did not match", 1, target.networks().size());
        assertEquals("Network did not match", NETWORK_NAME, target.network(NETWORK_ID).getName());

        final Network updated = NeutronNetwork.builder()
                .from(NETWORK_COPY)
                .name(UPDATED_NAME)
                .build();
        target.updateNetwork(updated);

        assertEquals("Number of networks did not match", 1, target.networks().size());
        assertEquals("Network did not match", UPDATED_NAME, target.network(NETWORK_ID).getName());
        validateEvents(OPENSTACK_NETWORK_CREATED, OPENSTACK_NETWORK_UPDATED);
    }

    /**
     * Tests if creating a null network fails with an exception.
     */
    @Test(expected = NullPointerException.class)
    public void testCreateNullNetwork() {
        target.createNetwork(null);
    }

    /**
     * Tests if creating a network with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateNetworkWithNullId() {
        final Network testNet = NeutronNetwork.builder().build();
        target.createNetwork(testNet);
    }

    /**
     * Tests if creating a duplicate network fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateDuplicateNetwork() {
        target.createNetwork(NETWORK);
        target.createNetwork(NETWORK);
    }

    /**
     * Tests if removing network with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testRemoveNetworkWithNull() {
        target.removeNetwork(null);
    }

    /**
     * Tests if updating a network with null name fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateNetworkWithNullName() {
        final Network updated = NeutronNetwork.builder()
                .name(null)
                .build();
        updated.setId(NETWORK_ID);
        target.updateNetwork(updated);
    }

    /**
     * Tests if updating an unregistered network fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateUnregisteredNetwork() {
        target.updateNetwork(NETWORK);
    }

    /**
     * Tests if updating a network with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateNetworkWithNullId() {
        final Network testNet = NeutronNetwork.builder().build();
        target.updateNetwork(testNet);
    }


    /**
     * Tests if getting all subnets returns the correct set of subnets.
     */
    @Test
    public void testGetSubnets() {
        createBasicNetworks();
        assertEquals("Number of subnet did not match", 1, target.subnets().size());
    }

    @Test
    public void testGetSubnetsByNetworkId() {
        createBasicNetworks();
        assertEquals("Subnet did not match", 1, target.subnets(NETWORK_ID).size());
        assertEquals("Subnet did not match", 0, target.subnets(UNKNOWN_ID).size());
    }

    /**
     * Tests if getting a subnet with ID returns the correct subnet.
     */
    @Test
    public void testGetSubnetById() {
        createBasicNetworks();
        assertTrue("Subnet did not match", target.subnet(SUBNET_ID) != null);
        assertTrue("Subnet did not match", target.subnet(UNKNOWN_ID) == null);
    }

    /**
     * Tests creating and removing a subnet, and checks if it triggers proper events.
     */
    @Test
    public void testCreateAndRemoveSubnet() {
        target.createSubnet(SUBNET);
        assertEquals("Number of subnet did not match", 1, target.subnets().size());
        assertTrue("Subnet was not created", target.subnet(SUBNET_ID) != null);

        target.removeSubnet(SUBNET_ID);
        assertEquals("Number of subnet did not match", 0, target.subnets().size());
        assertTrue("Subnet was not removed", target.subnet(SUBNET_ID) == null);

        validateEvents(OPENSTACK_SUBNET_CREATED, OPENSTACK_SUBNET_REMOVED);
    }

    /**
     * Tests updating a subnet, and checks if it triggers proper events.
     */
    @Test
    public void testCreateAndUpdateSubnet() {
        target.createSubnet(SUBNET_COPY);
        assertEquals("Number of subnet did not match", 1, target.subnets().size());
        assertEquals("Subnet did not match", null, target.subnet(SUBNET_ID).getName());

        // TODO fix NeutronSubnet.builder().from() in openstack4j
        final Subnet updated = NeutronSubnet.builder()
                .networkId(NETWORK_ID)
                .cidr("192.168.0.0/24")
                .name(UPDATED_NAME)
                .build();
        updated.setId(SUBNET_ID);
        target.updateSubnet(updated);

        assertEquals("Number of subnet did not match", 1, target.subnets().size());
        assertEquals("Subnet did not match", UPDATED_NAME, target.subnet(SUBNET_ID).getName());

        validateEvents(OPENSTACK_SUBNET_CREATED, OPENSTACK_SUBNET_UPDATED);
    }

    /**
     * Tests if creating a null subnet fails with an exception.
     */
    @Test(expected = NullPointerException.class)
    public void testCreateNullSubnet() {
        target.createSubnet(null);
    }

    /**
     * Tests if creating a subnet with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateSubnetWithNullId() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .networkId(NETWORK_ID)
                .cidr("192.168.0.0/24")
                .build();
        target.createSubnet(testSubnet);
    }

    /**
     * Tests if creating subnet with null network ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateSubnetWithNullNetworkId() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .cidr("192.168.0.0/24")
                .build();
        testSubnet.setId(SUBNET_ID);
        target.createSubnet(testSubnet);
    }

    /**
     * Tests if creating a subnet with null CIDR fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateSubnetWithNullCidr() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .networkId(NETWORK_ID)
                .build();
        testSubnet.setId(SUBNET_ID);
        target.createSubnet(testSubnet);
    }

    /**
     * Tests if creating a duplicate subnet fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreateDuplicateSubnet() {
        target.createSubnet(SUBNET);
        target.createSubnet(SUBNET);
    }

    /**
     * Tests if updating an unregistered subnet fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateUnregisteredSubnet() {
        target.updateSubnet(SUBNET);
    }

    /**
     * Tests if updating a null subnet fails with an exception.
     */
    @Test(expected = NullPointerException.class)
    public void testUpdateSubnetWithNull() {
        target.updateSubnet(null);
    }

    /**
     * Tests if updating a subnet with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateSubnetWithNullId() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .networkId(NETWORK_ID)
                .cidr("192.168.0.0/24")
                .build();
        target.updateSubnet(testSubnet);
    }

    /**
     * Tests if updating a subnet with null network ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateSubnetWithNullNetworkId() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .cidr("192.168.0.0/24")
                .build();
        testSubnet.setId(SUBNET_ID);
        target.updateSubnet(testSubnet);
    }

    /**
     * Tests if updating a subnet with null CIDR fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateSubnetWithNullCidr() {
        final Subnet testSubnet = NeutronSubnet.builder()
                .networkId(NETWORK_ID)
                .build();
        testSubnet.setId(SUBNET_ID);
        target.updateSubnet(testSubnet);
    }

    /**
     * Tests if getting all ports returns correct set of values.
     */
    @Test
    public void testGetPorts() {
        createBasicNetworks();
        assertEquals("Number of port did not match", 1, target.ports().size());
    }

    /**
     * Tests if getting a port with network ID returns correct set of values.
     */
    @Test
    public void testGetPortsByNetworkId() {
        createBasicNetworks();
        assertEquals("Number of port did not match", 1, target.ports(NETWORK_ID).size());
        assertEquals("Number of port did not match", 0, target.ports(UNKNOWN_ID).size());
    }

    /**
     * Tests if getting a port with ID returns correct value.
     */
    @Test
    public void testGetPortById() {
        createBasicNetworks();
        assertTrue("Port did not match", target.port(PORT_ID) != null);
        assertTrue("Port did not match", target.port(UNKNOWN_ID) == null);
    }

    /**
     * Tests creating and removing a port, and checks if proper event is triggered.
     */
    @Test
    public void testCreateAndRemovePort() {
        target.createPort(PORT);
        assertEquals("Number of port did not match", 1, target.ports().size());
        assertTrue("Port was not created", target.port(PORT_ID) != null);

        target.removePort(PORT_ID);
        assertEquals("Number of port did not match", 0, target.ports().size());
        assertTrue("Port was not created", target.port(PORT_ID) == null);

        validateEvents(OPENSTACK_PORT_CREATED, OPENSTACK_PORT_REMOVED);
    }

    /**
     * Tests creating and updating a port, and checks if proper event is triggered.
     */
    @Test
    public void testCreateAndUpdatePort() {
        target.createPort(PORT);
        assertEquals("Number of port did not match", 1, target.ports().size());
        assertEquals("Port did not match", null, target.port(PORT_ID).getName());

        final Port updated = PORT_COPY.toBuilder()
                .name(UPDATED_NAME)
                .build();
        target.updatePort(updated);

        assertEquals("Number of port did not match", 1, target.ports().size());
        assertEquals("Port did not match", UPDATED_NAME, target.port(PORT_ID).getName());

        validateEvents(OPENSTACK_PORT_CREATED, OPENSTACK_PORT_UPDATED);
    }

    /**
     * Tests if creating a null port fails with an exception.
     */
    @Test(expected = NullPointerException.class)
    public void testCreateNullPort() {
        target.createPort(null);
    }

    /**
     * Tests if creating a port with null ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreatePortWithNullId() {
        final Port testPort = NeutronPort.builder()
                .networkId(NETWORK_ID)
                .build();
        target.createPort(testPort);
    }

    /**
     * Tests if creating a port with null network ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testCreatePortWithNullNetworkId() {
        final Port testPort = NeutronPort.builder().build();
        testPort.setId(PORT_ID);
        target.createPort(testPort);
    }

    /**
     * Tests if creating a duplicate port fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void createDuplicatePort() {
        target.createPort(PORT);
        target.createPort(PORT);
    }

    /**
     * Tests if updating an unregistered port fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdateUnregisteredPort() {
        target.updatePort(PORT);
    }

    /**
     * Tests if updating a null port fails with an exception.
     */
    @Test(expected = NullPointerException.class)
    public void testUpdateNullPort() {
        target.updatePort(null);
    }

    /**
     * Tests if updating a port with null ID fails with exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdatePortWithNullId() {
        final Port testPort = NeutronPort.builder()
                .networkId(NETWORK_ID)
                .build();
        target.updatePort(testPort);
    }

    /**
     * Tests if updating a port with null network ID fails with an exception.
     */
    @Test(expected = IllegalArgumentException.class)
    public void testUpdatePortWithNullNetworkId() {
        final Port testPort = NeutronPort.builder().build();
        testPort.setId(PORT_ID);
        target.updatePort(testPort);
    }

    private void createBasicNetworks() {
        target.createNetwork(NETWORK);
        target.createSubnet(SUBNET);
        target.createPort(PORT);
    }

    private static class TestCoreService extends CoreServiceAdapter {

        @Override
        public ApplicationId registerApplication(String name) {
            return TEST_APP_ID;
        }
    }

    private static class TestOpenstackNodeManager implements OpenstackNodeService, OpenstackNodeAdminService {
        Map<String, OpenstackNode> osNodeMap = Maps.newHashMap();
        List<OpenstackNodeListener> listeners = Lists.newArrayList();

        @Override
        public Set<OpenstackNode> nodes() {
            return ImmutableSet.copyOf(osNodeMap.values());
        }

        @Override
        public Set<OpenstackNode> nodes(OpenstackNode.NodeType type) {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.type() == type)
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<OpenstackNode> completeNodes() {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.state() == COMPLETE)
                    .collect(Collectors.toSet());
        }

        @Override
        public Set<OpenstackNode> completeNodes(OpenstackNode.NodeType type) {
            return osNodeMap.values().stream()
                    .filter(osNode -> osNode.type() == type && osNode.state() == COMPLETE)
                    .collect(Collectors.toSet());
        }

        @Override
        public OpenstackNode node(String hostname) {
            return osNodeMap.get(hostname);
        }

        @Override
        public OpenstackNode node(DeviceId deviceId) {
            return osNodeMap.values().stream()
                    .filter(osNode -> Objects.equals(osNode.intgBridge(), deviceId) ||
                            Objects.equals(osNode.ovsdb(), deviceId))
                    .findFirst().orElse(null);
        }

        @Override
        public void addVfPort(OpenstackNode osNode, String portName) {
        }

        @Override
        public void removeVfPort(OpenstackNode osNode, String portName) {
        }

        @Override
        public void addListener(OpenstackNodeListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeListener(OpenstackNodeListener listener) {
            listeners.remove(listener);
        }

        @Override
        public void createNode(OpenstackNode osNode) {
            osNodeMap.put(osNode.hostname(), osNode);
        }

        @Override
        public void updateNode(OpenstackNode osNode) {
            osNodeMap.put(osNode.hostname(), osNode);
        }

        @Override
        public OpenstackNode removeNode(String hostname) {
            return null;
        }
    }

    private static class TestOpenstackNetworkListener implements OpenstackNetworkListener {
        private List<OpenstackNetworkEvent> events = Lists.newArrayList();

        @Override
        public void event(OpenstackNetworkEvent event) {
            events.add(event);
        }
    }

    private void validateEvents(Enum... types) {
        int i = 0;
        assertEquals("Number of events did not match", types.length, testListener.events.size());
        for (Event event : testListener.events) {
            assertEquals("Incorrect event received", types[i], event.type());
            i++;
        }
        testListener.events.clear();
    }
}