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

import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
import org.onosproject.incubator.net.virtual.NetworkId;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualDevice;
import org.onosproject.incubator.net.virtual.VirtualHost;
import org.onosproject.incubator.net.virtual.VirtualLink;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.Link;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.onosproject.net.provider.ProviderId;

import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;

public class DefaultVirtualPacketProviderTest {
    private static final String SRC_MAC_ADDR = "00:00:00:00:00:00";
    private static final String DST_MAC_ADDR = "00:00:00:00:00:01";
    private static final ProviderId PID = new ProviderId("of", "foo");

    private static final DeviceId DID1 = DeviceId.deviceId("of:001");
    private static final DeviceId DID2 = DeviceId.deviceId("of:002");
    private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
    private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
    private static final PortNumber PORT_NUM3 = PortNumber.portNumber(3);
    private static final PortNumber PORT_NUM4 = PortNumber.portNumber(4);

    private static final DefaultAnnotations ANNOTATIONS =
            DefaultAnnotations.builder().set("foo", "bar").build();

    private static final Device DEV1 =
            new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
    private static final Device DEV2 =
            new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
    private static final Port PORT11 =
            new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
    private static final Port PORT12 =
            new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
    private static final Port PORT21 =
            new DefaultPort(DEV2, PORT_NUM3, true, ANNOTATIONS);
    private static final Port PORT22 =
            new DefaultPort(DEV2, PORT_NUM4, true, ANNOTATIONS);

    private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
    private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
    private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM3);
    private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM4);
    private static final Link LINK1 = DefaultLink.builder()
            .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();

    private static final TenantId TENANT_ID = TenantId.tenantId("1");
    private static final NetworkId VNET_ID = NetworkId.networkId(1);
    private static final DeviceId VDID = DeviceId.deviceId("of:100");

    private static final PortNumber VPORT_NUM1 = PortNumber.portNumber(10);
    private static final PortNumber VPORT_NUM2 = PortNumber.portNumber(11);

    private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
            VNET_ID, TenantId.tenantId("t1"));
    private static final VirtualDevice VDEV =
            new DefaultVirtualDevice(VNET_ID, VDID);
    private static final VirtualPort VPORT1 =
            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM1, CP11);
    private static final VirtualPort VPORT2 =
            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM2, CP22);
    private static final ConnectPoint VCP11 = new ConnectPoint(VDID, VPORT_NUM1);
    private static final ConnectPoint VCP12 = new ConnectPoint(VDID, VPORT_NUM2);

    protected DefaultVirtualPacketProvider virtualProvider;
    protected TestPacketService testPacketService;
    protected TestVirtualPacketProviderService providerService;

    private VirtualProviderManager providerManager;

    private ApplicationId vAppId;

    @Before
    public void setUp() {
        virtualProvider = new DefaultVirtualPacketProvider();

        virtualProvider.coreService = new CoreServiceAdapter();
        virtualProvider.virtualNetworkAdminService =
                new TestVirtualNetworkAdminService();

        providerService = new TestVirtualPacketProviderService();

        testPacketService = new TestPacketService();
        virtualProvider.packetService = testPacketService;

        providerManager = new VirtualProviderManager();
        virtualProvider.providerRegistryService = providerManager;
        providerManager.registerProviderService(VNET_ID, providerService);

        virtualProvider.activate();
        vAppId = new TestApplicationId(0, "Virtual App");
    }

    @After
    public void tearDown() {
        virtualProvider.deactivate();
        virtualProvider.coreService = null;
        virtualProvider.virtualNetworkAdminService = null;
        virtualProvider.providerService = null;
    }


    /** Test the virtual outbound packet is delivered to a proper (physical)
     *  device.
     */
    @Test
    public void devirtualizePacket() {
        TrafficTreatment tr = DefaultTrafficTreatment.builder()
                .setOutput(VPORT_NUM1).build();
        ByteBuffer data = ByteBuffer.wrap("abc".getBytes());

        OutboundPacket vOutPacket = new DefaultOutboundPacket(VDID, tr, data);

        virtualProvider.emit(VNET_ID, vOutPacket);

        assertEquals("The count should be 1", 1,
                     testPacketService.getRequestedPacketCount());

        OutboundPacket pOutPacket = testPacketService.getRequestedPacket(0);

        assertEquals("The packet should be requested on DEV1", DID1,
                     pOutPacket.sendThrough());

        PortNumber outPort = pOutPacket.treatment()
                .allInstructions()
                .stream()
                .filter(i -> i.type() == Instruction.Type.OUTPUT)
                .map(i -> (Instructions.OutputInstruction) i)
                .map(i -> i.port())
                .findFirst().get();
        assertEquals("The packet should be out at PORT1 of DEV1", PORT_NUM1,
                     outPort);
    }

    /** Test the physical packet context is delivered to a proper (physical)
     *  virtual network and device.
     */
    @Test
    public void virtualizePacket() {
        Ethernet eth = new Ethernet();
        eth.setSourceMACAddress(SRC_MAC_ADDR);
        eth.setDestinationMACAddress(DST_MAC_ADDR);
        eth.setVlanID((short) 1);
        eth.setPayload(null);

        InboundPacket pInPacket =
                new DefaultInboundPacket(CP22, eth,
                                         ByteBuffer.wrap(eth.serialize()));

        PacketContext pContext =
                new TestPacketContext(System.nanoTime(), pInPacket, null, false);

        testPacketService.sendTestPacketContext(pContext);

        PacketContext vContext = providerService.getRequestedPacketContext(0);
        InboundPacket vInPacket = vContext.inPacket();

        assertEquals("the packet should be received from VCP12",
                     VCP12, vInPacket.receivedFrom());

        assertEquals("VLAN tag should be excludede", VlanId.UNTAGGED,
                     vInPacket.parsed().getVlanID());
    }

    private class TestPacketContext extends DefaultPacketContext {

        /**
         * Creates a new packet context.
         *
         * @param time   creation time
         * @param inPkt  inbound packet
         * @param outPkt outbound packet
         * @param block  whether the context is blocked or not
         */
        protected TestPacketContext(long time, InboundPacket inPkt,
                                    OutboundPacket outPkt, boolean block) {
            super(time, inPkt, outPkt, block);
        }

        @Override
        public void send() {

        }
    }

    private static class TestApplicationId extends DefaultApplicationId {
        public TestApplicationId(int id, String name) {
            super(id, name);
        }
    }

    private static class TestVirtualNetworkAdminService
            implements VirtualNetworkAdminService {

        @Override
        public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
            return ImmutableSet.of(VNET);
        }

        @Override
        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
            return ImmutableSet.of(VDEV);
        }

        @Override
        public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
            return null;
        }

        @Override
        public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
            return null;
        }

        @Override
        public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
                                                DeviceId deviceId) {
            return ImmutableSet.of(VPORT1, VPORT2);
        }

        @Override
        public <T> T get(NetworkId networkId, Class<T> serviceClass) {
            return null;
        }

        @Override
        public ServiceDirectory getServiceDirectory() {
            return null;
        }

        @Override
        public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
            return null;
        }

        @Override
        public void registerTenantId(TenantId tenantId) {

        }

        @Override
        public void unregisterTenantId(TenantId tenantId) {

        }

        @Override
        public Set<TenantId> getTenantIds() {
            return ImmutableSet.of(TENANT_ID);
        }

        @Override
        public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
            return null;
        }

        @Override
        public void removeVirtualNetwork(NetworkId networkId) {

        }

        @Override
        public VirtualDevice createVirtualDevice(NetworkId networkId,
                                                 DeviceId deviceId) {
            return null;
        }

        @Override
        public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {

        }

        @Override
        public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
                                             MacAddress mac, VlanId vlan,
                                             HostLocation location,
                                             Set<IpAddress> ips) {
            return null;
        }

        @Override
        public void removeVirtualHost(NetworkId networkId, HostId hostId) {

        }

        @Override
        public VirtualLink createVirtualLink(NetworkId networkId,
                                             ConnectPoint src, ConnectPoint dst) {
            return null;
        }

        @Override
        public void removeVirtualLink(NetworkId networkId,
                                      ConnectPoint src, ConnectPoint dst) {

        }

        @Override
        public VirtualPort createVirtualPort(NetworkId networkId,
                                             DeviceId deviceId,
                                             PortNumber portNumber,
                                             ConnectPoint realizedBy) {
            return null;
        }

        @Override
        public void bindVirtualPort(NetworkId networkId,
                                    DeviceId deviceId,
                                    PortNumber portNumber,
                                    ConnectPoint realizedBy) {

        }

        @Override
        public void removeVirtualPort(NetworkId networkId, DeviceId deviceId,
                                      PortNumber portNumber) {

        }
    }

    private static class TestVirtualPacketProviderService
            extends AbstractVirtualProviderService<VirtualPacketProvider>
            implements VirtualPacketProviderService {
        static List<PacketContext> requestedContext = new LinkedList();
        static List<NetworkId> requestedNetworkId = new LinkedList();

        @Override
        public VirtualPacketProvider provider() {
            return null;
        }

        public NetworkId getRequestedNetworkId(int index) {
            return requestedNetworkId.get(index);
        }

        public PacketContext getRequestedPacketContext(int index) {
            return requestedContext.get(index);
        }

        @Override
        public void processPacket(PacketContext context) {
            requestedContext.add(context);
        }
    }

    private static class TestPacketService extends PacketServiceAdapter {
        static List<OutboundPacket> requestedPacket = new LinkedList();
        static PacketProcessor processor = null;

        @Override
        public void addProcessor(PacketProcessor processor, int priority) {
            this.processor = processor;
        }

        @Override
        public void emit(OutboundPacket packet) {
            requestedPacket.add(packet);
        }

        public OutboundPacket getRequestedPacket(int index) {
            return requestedPacket.get(index);
        }

        public int getRequestedPacketCount() {
            return requestedPacket.size();
        }

        public void sendTestPacketContext(PacketContext context) {
            processor.process(context);
        }
    }
}
