/*
 * Copyright 2018-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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.packet.DefaultInboundPacket;
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.openstacknetworking.api.InstancePort;

import java.nio.ByteBuffer;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.openstacknetworking.api.Constants.ARP_PROXY_MODE;

public class OpenstackSwitchingArpHandlerTest {

    private OpenstackSwitchingArpHandler arpHandler;

    protected PacketProcessor packetProcessor;

    private static final MacAddress CLIENT_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
    private static final IpAddress CLIENT_IP = IpAddress.valueOf("10.10.10.10");
    private static final IpAddress TARGET_IP = IpAddress.valueOf("10.10.10.20");
    private static final MacAddress EXPECTED_MAC = MacAddress.valueOf("2b:2b:2b:2b:2b:2b");

    @Before
    public void setUp() {
        arpHandler = new OpenstackSwitchingArpHandler();
        arpHandler.coreService = new TestCoreService();
        arpHandler.configService = new TestConfigService();
        arpHandler.instancePortService = new TestInstancePortService();
        arpHandler.packetService = new TestPacketService();
        arpHandler.osNetworkService = new TestOpenstackNetworkService();
        arpHandler.osNodeService = new TestOpenstackNodeService();
        arpHandler.osFlowRuleService = new TestOpenstackFlowRuleService();
        arpHandler.arpMode = ARP_PROXY_MODE;
        arpHandler.clusterService = new TestClusterService();
        arpHandler.leadershipService = new TestLeadershipService();
        arpHandler.activate();
    }

    @After
    public void tearDown() {
        arpHandler.deactivate();
    }

    /**
     * Tests the response to an ARP Request Packet.
     */
    @Test
    public void testRequest() {
        Ethernet arpRequest = constructArpPacket(ARP.OP_REQUEST);
        sendPacket(arpRequest);
    }

    /**
     * Sends an Ethernet packet to the process method of the Packet processor.
     *
     * @param ethernet Ethernet packet
     */
    private void sendPacket(Ethernet ethernet) {
        final ByteBuffer byteBuffer = ByteBuffer.wrap(ethernet.serialize());
        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
                ethernet,
                byteBuffer);

        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
        packetProcessor.process(context);
    }

    /**
     * Validates the contents of the packet sent by the OpenstackSwitchingArpHandler.
     *
     * @param packet Ethernet packet received
     */
    private void validatePacket(Ethernet packet) {
        ARP arpPacket = (ARP) packet.getPayload();

        assertEquals(arpPacket.getOpCode(), ARP.OP_REPLY);
        assertArrayEquals(arpPacket.getSenderHardwareAddress(), EXPECTED_MAC.toBytes());
        assertArrayEquals(arpPacket.getSenderProtocolAddress(), TARGET_IP.toOctets());
        assertArrayEquals(arpPacket.getTargetHardwareAddress(), CLIENT_MAC.toBytes());
        assertArrayEquals(arpPacket.getTargetProtocolAddress(), CLIENT_IP.toOctets());
        assertEquals(arpPacket.getProtocolType(), ARP.PROTO_TYPE_IP);
        assertEquals(arpPacket.getHardwareType(), ARP.HW_TYPE_ETHERNET);
    }

    /**
     * Constructs an Ethernet packet containing an ARP payload.
     *
     * @return Ethernet packet
     */
    private Ethernet constructArpPacket(short pktType) {
        if (pktType == ARP.OP_REQUEST) {

            return ARP.buildArpRequest(
                    CLIENT_MAC.toBytes(),
                    CLIENT_IP.toOctets(),
                    TARGET_IP.toOctets(),
                    (short) 2);
        }

        return null;
    }

    /**
     * Mocks the CoreService.
     */
    private class TestCoreService extends CoreServiceAdapter {
        @Override
        public ApplicationId registerApplication(String name) {
            return new DefaultApplicationId(100, "arpTestApp");
        }
    }

    /**
     * Mocks the ComponentConfigRegistry.
     */
    private class TestConfigService extends ComponentConfigAdapter {
    }

    /**
     * Mocks the ClusterService.
     */
    private class TestClusterService extends ClusterServiceAdapter {
    }

    /**
     * Mocks the LeadershipService.
     */
    private class TestLeadershipService extends LeadershipServiceAdapter {
    }

    /**
     * Mocks the OpenstackNodeService.
     */
    private class TestOpenstackNodeService extends OpenstackNodeServiceAdapter {
    }

    /**
     * Mocks the OpenstackFlowRuleService.
     */
    private class TestOpenstackFlowRuleService extends OpenstackFlowRuleServiceAdapter {
    }

    /**
     * Mocks the InstancePortService.
     */
    private class TestInstancePortService extends InstancePortServiceAdapter {

        @Override
        public InstancePort instancePort(MacAddress macAddress) {
            return new TestInstancePort();
        }

        @Override
        public InstancePort instancePort(IpAddress ipAddress, String osNetId) {
            return new TestInstancePort();
        }
    }

    /**
     * Mocks the instance port.
     */
    private final class TestInstancePort implements InstancePort {

        @Override
        public String networkId() {
            return null;
        }

        @Override
        public String portId() {
            return null;
        }

        @Override
        public MacAddress macAddress() {
            return EXPECTED_MAC;
        }

        @Override
        public IpAddress ipAddress() {
            return null;
        }

        @Override
        public DeviceId deviceId() {
            return null;
        }

        @Override
        public PortNumber portNumber() {
            return null;
        }
    }

    /**
     * Mocks the DefaultPacket context.
     */
    private final class TestPacketContext extends DefaultPacketContext {
        private TestPacketContext(long time, InboundPacket inPkt,
                                  OutboundPacket outPkt, boolean block) {
            super(time, inPkt, outPkt, block);
        }

        @Override
        public void send() {
            // We don't send anything out.
        }
    }

    /**
     * Keeps a reference to the PacketProcessor and verifies the OutboundPackets.
     */
    private class TestPacketService extends PacketServiceAdapter {
        @Override
        public void addProcessor(PacketProcessor processor, int priority) {
            packetProcessor = processor;
        }

        @Override
        public void emit(OutboundPacket packet) {
            try {
                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
                        0, packet.data().array().length);
                validatePacket(eth);
            } catch (Exception e) {
                fail(e.getMessage());
            }
        }
    }

    /**
     * Mocks the OpenstackNetworkService.
     */
    private class TestOpenstackNetworkService extends OpenstackNetworkServiceAdapter {
    }
}
