/*
 * 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 com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.DHCP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
import org.onlab.packet.dhcp.DhcpOption;
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.HostId;
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 org.openstack4j.model.network.AllowedAddressPair;
import org.openstack4j.model.network.HostRoute;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.IPVersionType;
import org.openstack4j.model.network.Ipv6AddressMode;
import org.openstack4j.model.network.Ipv6RaMode;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Pool;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.State;
import org.openstack4j.model.network.Subnet;
import org.openstack4j.model.network.builder.NetworkBuilder;
import org.openstack4j.model.network.builder.PortBuilder;
import org.openstack4j.model.network.builder.SubnetBuilder;
import org.openstack4j.openstack.networking.domain.NeutronHostRoute;
import org.openstack4j.openstack.networking.domain.NeutronIP;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_Classless_Static_Route;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_DomainServer;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_END;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_RequestedIP;
import static org.onosproject.net.NetTestTools.connectPoint;

/**
 * Unit tests for Openstack switching DHCP handler.
 */
public class OpenstackSwitchingDhcpHandlerTest {

    private OpenstackSwitchingDhcpHandler dhcpHandler;

    protected PacketProcessor packetProcessor;

    private static final byte DHCP_OPTION_MTU = (byte) 26;

    private static final short MTU = 1450;
    private static final HostId CLIENT_HOST =
                         HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
    private static final String EXPECTED_IP = "10.2.0.2";
    private static final String EXPECTED_CIDR = "10.2.0.0/24";
    private static final String EXPECTED_GATEWAY = "10.2.0.1";
    private static final Ip4Address BROADCAST =
                         Ip4Address.valueOf("255.255.255.255");
    private static final int TRANSACTION_ID = 1986;
    private static final Ip4Address DEFAULT_PRIMARY_DNS = Ip4Address.valueOf("8.8.8.8");
    private static final Ip4Address DEFAULT_SECONDARY_DNS = Ip4Address.valueOf("8.8.4.4");
    private static final String HOST_ROUTE_1_DESTINATION = "0.0.0.0/0";
    private static final String HOST_ROUTE_1_NEXTHOP = "10.2.0.1";
    private static final String HOST_ROUTE_2_DESTINATION = "10.0.0.0/8";
    private static final String HOST_ROUTE_2_NEXTHOP = "10.2.0.1";
    private static final String HOST_ROUTE_3_DESTINATION = "10.0.0.0/16";
    private static final String HOST_ROUTE_3_NEXTHOP = "10.2.0.1";
    private static final String HOST_ROUTE_4_DESTINATION = "10.0.0.0/24";
    private static final String HOST_ROUTE_4_NEXTHOP = "10.2.0.1";
    private static final HostRoute HOST_ROUTE_1 = new NeutronHostRoute(HOST_ROUTE_1_DESTINATION, HOST_ROUTE_1_NEXTHOP);
    private static final HostRoute HOST_ROUTE_2 = new NeutronHostRoute(HOST_ROUTE_2_DESTINATION, HOST_ROUTE_2_NEXTHOP);
    private static final HostRoute HOST_ROUTE_3 = new NeutronHostRoute(HOST_ROUTE_3_DESTINATION, HOST_ROUTE_3_NEXTHOP);
    private static final HostRoute HOST_ROUTE_4 = new NeutronHostRoute(HOST_ROUTE_4_DESTINATION, HOST_ROUTE_4_NEXTHOP);
    private static final int HOST_ROUTES_SIZE = 26;

    private static final String IP_SUBNET_ID = "1";

    private DHCP.MsgType testMsgType;

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

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

    /**
     * Tests the response to a DHCP Discover Packet.
     */
    @Test
    public void testDiscover() {
        Ethernet dhcpDiscover = constructDhcpPacket(DHCP.MsgType.DHCPDISCOVER);
        testMsgType = DHCP.MsgType.DHCPDISCOVER;
        sendPacket(dhcpDiscover);
    }

    /**
     * Tests the response to a DHCP Request Packet.
     */
    @Test
    public void testRequest() {
        Ethernet dhcpRequest = constructDhcpPacket(DHCP.MsgType.DHCPREQUEST);
        testMsgType = DHCP.MsgType.DHCPREQUEST;
        sendPacket(dhcpRequest);
    }

    /**
     * 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 OpenstackSwitchingDhcpHandler.
     *
     * @param packet Ethernet packet received
     */
    private void validatePacket(Ethernet packet) {
        DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
        assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT_HOST.mac());
        assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
        assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);

        if (testMsgType == DHCP.MsgType.DHCPDISCOVER) {
            assertEquals(dhcpPacket.getPacketType(), DHCP.MsgType.DHCPOFFER);
        }

        if (testMsgType == DHCP.MsgType.DHCPREQUEST) {
            assertEquals(dhcpPacket.getPacketType(), DHCP.MsgType.DHCPACK);
        }
    }

    /**
     * Constructs an Ethernet packet containing a DHCP payload.
     *
     * @param msgType DHCP message type
     * @return Ethernet packet
     */
    private Ethernet constructDhcpPacket(DHCP.MsgType msgType) {

        // Ethernet frame
        Ethernet ethFrame = new Ethernet();
        ethFrame.setSourceMACAddress(CLIENT_HOST.mac());
        ethFrame.setDestinationMACAddress(MacAddress.BROADCAST);
        ethFrame.setEtherType(Ethernet.TYPE_IPV4);
        ethFrame.setVlanID((short) 2);

        // IP packet
        IPv4 ipv4Pkt = new IPv4();
        ipv4Pkt.setSourceAddress(0);
        ipv4Pkt.setDestinationAddress(BROADCAST.toInt());
        ipv4Pkt.setTtl((byte) 127);

        // UDP datagram
        UDP udpDatagram = new UDP();
        udpDatagram.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
        udpDatagram.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);

        // DHCP payload
        DHCP dhcp = new DHCP();

        dhcp.setOpCode(DHCP.OPCODE_REQUEST);

        dhcp.setYourIPAddress(0);
        dhcp.setServerIPAddress(0);

        dhcp.setTransactionId(TRANSACTION_ID);
        dhcp.setClientHardwareAddress(CLIENT_HOST.mac().toBytes());
        dhcp.setHardwareType(DHCP.HWTYPE_ETHERNET);
        dhcp.setHardwareAddressLength((byte) 6);

        // DHCP options start...
        DhcpOption option = new DhcpOption();
        List<DhcpOption> optionList = new ArrayList<>();

        // DHCP message type
        option.setCode(OptionCode_MessageType.getValue());
        option.setLength((byte) 1);
        byte[] optionData = {(byte) msgType.getValue()};
        option.setData(optionData);
        optionList.add(option);

        // DHCP requested IP address
        option = new DhcpOption();
        option.setCode(OptionCode_RequestedIP.getValue());
        option.setLength((byte) 4);
        optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
        option.setData(optionData);
        optionList.add(option);

        // DHCP domain server
        Subnet subnet = dhcpHandler.osNetworkService.subnet("subnet");

        option = new DhcpOption();
        option.setCode(OptionCode_DomainServer.getValue());
        option.setLength((byte) 8);
        ByteBuffer dnsByteBuf = ByteBuffer.allocate(8);
        dnsByteBuf.put(DEFAULT_PRIMARY_DNS.toOctets());
        dnsByteBuf.put(DEFAULT_SECONDARY_DNS.toOctets());
        option.setData(dnsByteBuf.array());
        optionList.add(option);

        // MTU
        option = new DhcpOption();
        option.setCode(DHCP_OPTION_MTU);
        option.setLength((byte) 2);
        option.setData(ByteBuffer.allocate(2).putShort(MTU).array());
        optionList.add(option);

        // classless static route
        option = new DhcpOption();
        option.setCode(OptionCode_Classless_Static_Route.getValue());

        option.setLength((byte) HOST_ROUTES_SIZE);
        ByteBuffer hostRouteByteBuf = ByteBuffer.allocate(HOST_ROUTES_SIZE);

        subnet.getHostRoutes().forEach(h -> {
            IpPrefix ipPrefix = IpPrefix.valueOf(h.getDestination());
            hostRouteByteBuf.put(bytesDestinationDescriptor(ipPrefix));
            hostRouteByteBuf.put(Ip4Address.valueOf(h.getNexthop()).toOctets());
        });

        option.setData(hostRouteByteBuf.array());
        optionList.add(option);

        // DHCP options end...
        option = new DhcpOption();
        option.setCode(OptionCode_END.getValue());
        option.setLength((byte) 1);
        optionList.add(option);

        dhcp.setOptions(optionList);

        udpDatagram.setPayload(dhcp);
        ipv4Pkt.setPayload(udpDatagram);
        ethFrame.setPayload(ipv4Pkt);

        return ethFrame;
    }

    private byte[] bytesDestinationDescriptor(IpPrefix ipPrefix) {
        ByteBuffer byteBuffer;
        int prefixLen = ipPrefix.prefixLength();

        // retrieve ipPrefix to the destination descriptor format
        // ex) 10.1.1.0/24 -> [10,1,1,0]
        String[] ipPrefixString = ipPrefix.getIp4Prefix().toString()
                .split("/")[0]
                .split("\\.");

        // retrieve destination descriptor and put this to bytebuffer according to RFC 3442
        // ex) 0.0.0.0/0 -> 0
        // ex) 10.0.0.0/8 -> 8.10
        // ex) 10.17.0.0/16 -> 16.10.17
        // ex) 10.27.129.0/24 -> 24.10.27.129
        // ex) 10.229.0.128/25 -> 25.10.229.0.128
        for (int i = 0; i <= 4; i++) {
            if (prefixLen == Math.min(prefixLen, i * 8)) {
                byteBuffer = ByteBuffer.allocate(i + 1);
                byteBuffer.put((byte) prefixLen);

                for (int j = 0; j < i; j++) {
                    byteBuffer.put((byte) Integer.parseInt(ipPrefixString[j]));
                }
                return byteBuffer.array();
            }
        }

        return null;
    }

    /**
     * Mocks the CoreService.
     */
    private class TestCoreService extends CoreServiceAdapter {

        @Override
        public ApplicationId registerApplication(String name) {
            return new DefaultApplicationId(100, "dhcpTestApp");
        }
    }

    /**
     * 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 InstancePortService.
     */
    private class TestInstancePortService extends InstancePortServiceAdapter {

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

    /**
     * Mocks the OpenstackNetworkService.
     */
    private class TestOpenstackNetworkService extends OpenstackNetworkServiceAdapter {
        @Override
        public Port port(String portId) {
            return new TestPort();
        }

        @Override
        public Subnet subnet(String subnetId) {
            return new TestSubnet();
        }

        @Override
        public Network network(String networkId) {
            return new TestNetwork();
        }

        /**
         * Mocks the Neutron port.
         */
        private class TestPort implements Port {

            @Override
            public State getState() {
                return null;
            }

            @Override
            public boolean isAdminStateUp() {
                return false;
            }

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

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

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

            @Override
            public Set<? extends IP> getFixedIps() {
                return ImmutableSet.of(new NeutronIP(EXPECTED_IP, IP_SUBNET_ID));
            }

            @Override
            public Set<? extends AllowedAddressPair> getAllowedAddressPairs() {
                return null;
            }

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

            @Override
            public List<String> getSecurityGroups() {
                return null;
            }

            @Override
            public Boolean isPortSecurityEnabled() {
                return null;
            }

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

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

            @Override
            public Map<String, Object> getVifDetails() {
                return null;
            }

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

            @Override
            public Map<String, Object> getProfile() {
                return null;
            }

            @Override
            public PortBuilder toBuilder() {
                return null;
            }

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

            @Override
            public void setTenantId(String tenantId) {

            }

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

            @Override
            public void setName(String name) {

            }

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

            @Override
            public void setId(String id) {

            }
        }

        /**
         * Mocks the Neutron network.
         */
        private class TestNetwork implements Network {

            @Override
            public State getStatus() {
                return null;
            }

            @Override
            public List<String> getSubnets() {
                return null;
            }

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

            @Override
            public boolean isAdminStateUp() {
                return false;
            }

            @Override
            public NetworkType getNetworkType() {
                return null;
            }

            @Override
            public boolean isRouterExternal() {
                return false;
            }

            @Override
            public boolean isShared() {
                return false;
            }

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

            @Override
            public List<? extends Subnet> getNeutronSubnets() {
                return null;
            }

            @Override
            public Integer getMTU() {
                return Integer.valueOf(4000);
            }

            @Override
            public List<String> getAvailabilityZoneHints() {
                return null;
            }

            @Override
            public List<String> getAvailabilityZones() {
                return null;
            }

            @Override
            public NetworkBuilder toBuilder() {
                return null;
            }

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

            @Override
            public void setTenantId(String s) {

            }

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

            @Override
            public void setName(String s) {

            }

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

            @Override
            public void setId(String s) {

            }
        }

        /**
         * Mocks the Neutron subnet.
         */
        private class TestSubnet implements Subnet {

            @Override
            public boolean isDHCPEnabled() {
                return false;
            }

            @Override
            public String getNetworkId() {
                return "1";
            }

            @Override
            public List<String> getDnsNames() {
                List<String> dnsServers = Lists.newArrayList();
                dnsServers.add(DEFAULT_PRIMARY_DNS.toString());
                dnsServers.add(DEFAULT_SECONDARY_DNS.toString());

                return dnsServers;
            }

            @Override
            public List<? extends Pool> getAllocationPools() {
                return null;
            }

            @Override
            public List<? extends HostRoute> getHostRoutes() {
                List<HostRoute> hostRoutes = Lists.newArrayList();

                hostRoutes.add(HOST_ROUTE_1);
                hostRoutes.add(HOST_ROUTE_2);
                hostRoutes.add(HOST_ROUTE_3);
                hostRoutes.add(HOST_ROUTE_4);

                return hostRoutes;
            }

            @Override
            public IPVersionType getIpVersion() {
                return null;
            }

            @Override
            public String getGateway() {
                return EXPECTED_GATEWAY;
            }

            @Override
            public String getCidr() {
                return EXPECTED_CIDR;
            }

            @Override
            public Ipv6AddressMode getIpv6AddressMode() {
                return null;
            }

            @Override
            public Ipv6RaMode getIpv6RaMode() {
                return null;
            }

            @Override
            public SubnetBuilder toBuilder() {
                return null;
            }

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

            @Override
            public void setTenantId(String tenantId) {

            }

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

            @Override
            public void setName(String name) {

            }

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

            @Override
            public void setId(String id) {

            }
        }
    }

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

    }

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

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

        @Override
        public IpAddress ipAddress() {
            return IpAddress.valueOf(EXPECTED_IP);
        }

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

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

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

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

        @Override
        public State state() {
            return null;
        }

        @Override
        public InstancePort updateState(State newState) {
            return null;
        }

        @Override
        public InstancePort updatePrevLocation(DeviceId oldDeviceId, PortNumber oldPortNumber) {
            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());
            }
        }
    }
}
