package org.onlab.onos.sdnip;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.easymock.IAnswer;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.onlab.junit.IntegrationTest;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.host.InterfaceIpAddress;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
import org.onlab.onos.net.intent.AbstractIntentTest;
import org.onlab.onos.sdnip.config.BgpPeer;
import org.onlab.onos.sdnip.config.Interface;
import org.onlab.onos.sdnip.config.SdnIpConfigurationService;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;

import com.google.common.collect.Sets;

/**
 * Integration tests for the SDN-IP application.
 * <p/>
 * The tests are very coarse-grained. They feed route updates in to
 * {@link Router} (simulating routes learnt from iBGP module inside SDN-IP
 * application), then they check that the correct intents are created and
 * submitted to the intent service. The entire route processing logic of
 * Router class is tested.
 */
@Category(IntegrationTest.class)
public class SdnIpTest extends AbstractIntentTest {
    private static final int MAC_ADDRESS_LENGTH = 6;
    private static final int MIN_PREFIX_LENGTH = 1;
    private static final int MAX_PREFIX_LENGTH = 32;

    private IntentSynchronizer intentSynchronizer;
    static Router router;

    private SdnIpConfigurationService sdnIpConfigService;
    private InterfaceService interfaceService;
    private HostService hostService;
    private IntentService intentService;

    private Map<IpAddress, BgpPeer> bgpPeers;

    private Random random;

    static final ConnectPoint SW1_ETH1 = new ConnectPoint(
            DeviceId.deviceId("of:0000000000000001"),
            PortNumber.portNumber(1));

    static final ConnectPoint SW2_ETH1 = new ConnectPoint(
            DeviceId.deviceId("of:0000000000000002"),
            PortNumber.portNumber(1));

    static final ConnectPoint SW3_ETH1 = new ConnectPoint(
            DeviceId.deviceId("of:0000000000000003"),
            PortNumber.portNumber(1));

    private static final ApplicationId APPID = new ApplicationId() {
        @Override
        public short id() {
            return 1;
        }

        @Override
        public String name() {
            return "SDNIP";
        }
    };

    @Before
    public void setUp() throws Exception {
        super.setUp();

        setUpInterfaceService();
        setUpSdnIpConfigService();

        hostService = new TestHostService();
        intentService = createMock(IntentService.class);
        random = new Random();

        intentSynchronizer = new IntentSynchronizer(APPID, intentService);
        router = new Router(APPID, intentSynchronizer, sdnIpConfigService,
                            interfaceService, hostService);
    }

    /**
     * Sets up InterfaceService and virtual {@link Interface}s.
     */
    private void setUpInterfaceService() {

        interfaceService = createMock(InterfaceService.class);

        Set<Interface> interfaces = Sets.newHashSet();

        Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
        interfaceIpAddresses1.add(new InterfaceIpAddress(
                IpAddress.valueOf("192.168.10.101"),
                IpPrefix.valueOf("192.168.10.0/24")));
        Interface sw1Eth1 = new Interface(SW1_ETH1,
                interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"));
        interfaces.add(sw1Eth1);

        Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
        interfaceIpAddresses2.add(new InterfaceIpAddress(
                IpAddress.valueOf("192.168.20.101"),
                IpPrefix.valueOf("192.168.20.0/24")));
        Interface sw2Eth1 = new Interface(SW2_ETH1,
                interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"));
        interfaces.add(sw2Eth1);

        Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
        interfaceIpAddresses3.add(new InterfaceIpAddress(
                IpAddress.valueOf("192.168.30.101"),
                IpPrefix.valueOf("192.168.30.0/24")));
        Interface sw3Eth1 = new Interface(SW3_ETH1,
                interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"));
        interfaces.add(sw3Eth1);

        expect(interfaceService.getInterface(SW1_ETH1)).andReturn(
                sw1Eth1).anyTimes();
        expect(interfaceService.getInterface(SW2_ETH1)).andReturn(
                sw2Eth1).anyTimes();
        expect(interfaceService.getInterface(SW3_ETH1)).andReturn(
                sw3Eth1).anyTimes();

        expect(interfaceService.getInterfaces()).andReturn(
                interfaces).anyTimes();
        replay(interfaceService);
    }

    /**
     * Sets up SdnIpConfigService and BGP peers in external networks.
     */
    private void setUpSdnIpConfigService() {

        sdnIpConfigService = createMock(SdnIpConfigurationService.class);

        bgpPeers = new HashMap<>();

        String peerSw1Eth1 = "192.168.10.1";
        bgpPeers.put(IpAddress.valueOf(peerSw1Eth1),
                new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));

        String peer1Sw2Eth1 = "192.168.20.1";
        bgpPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
                new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));

        String peer2Sw2Eth1 = "192.168.30.1";
        bgpPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
                new BgpPeer("00:00:00:00:00:00:00:03", 1, peer2Sw2Eth1));

        expect(sdnIpConfigService.getBgpPeers()).andReturn(bgpPeers).anyTimes();
        replay(sdnIpConfigService);
    }

    /**
     * Tests adding a set of routes into {@link Router}.
     * <p/>
     * Random routes are generated and fed in to the route processing
     * logic (via processRouteAdd in Router class). We check that the correct
     * intents are generated and submitted to our mock intent service.
     *
     * @throws InterruptedException if interrupted while waiting on a latch
     * @throws TestUtilsException if exceptions when using TestUtils
     */
    @Test
    public void testAddRoutes() throws InterruptedException, TestUtilsException {
        int numRoutes = 100;

        final CountDownLatch latch = new CountDownLatch(numRoutes);

        List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);

        // Set up expectation
        reset(intentService);

        for (RouteUpdate update : routeUpdates) {
            Ip4Address nextHopAddress = update.routeEntry().nextHop();

            // Find out the egress ConnectPoint
            ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);

            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
                    generateMacAddress(nextHopAddress),
                    egressConnectPoint);
            intentService.submit(TestIntentServiceHelper.eqExceptId(intent));

            expectLastCall().andAnswer(new IAnswer<Object>() {
                @Override
                public Object answer() throws Throwable {
                    latch.countDown();
                    return null;
                }
            }).once();
        }

        replay(intentService);

        intentSynchronizer.leaderChanged(true);
        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);

        // Add route updates
        router.processRouteUpdates(routeUpdates);

        latch.await(5000, TimeUnit.MILLISECONDS);

        assertEquals(router.getRoutes().size(), numRoutes);
        assertEquals(intentSynchronizer.getRouteIntents().size(),
                     numRoutes);

        verify(intentService);
    }

    /**
     * Tests adding then deleting a set of routes from {@link Router}.
     * <p/>
     * Random routes are generated and fed in to the route processing
     * logic (via processRouteAdd in Router class), and we check that the
     * correct intents are generated. We then delete the entire set of routes
     * (by feeding updates to processRouteDelete), and check that the correct
     * intents are withdrawn from the intent service.
     *
     * @throws InterruptedException if interrupted while waiting on a latch
     * @throws TestUtilsException exceptions when using TestUtils
     */
    @Test
    public void testDeleteRoutes() throws InterruptedException, TestUtilsException {
        int numRoutes = 100;
        List<RouteUpdate> routeUpdates = generateRouteUpdates(numRoutes);

        final CountDownLatch installCount = new CountDownLatch(numRoutes);
        final CountDownLatch deleteCount = new CountDownLatch(numRoutes);

        // Set up expectation
        reset(intentService);

        for (RouteUpdate update : routeUpdates) {
            Ip4Address nextHopAddress = update.routeEntry().nextHop();

            // Find out the egress ConnectPoint
            ConnectPoint egressConnectPoint = getConnectPoint(nextHopAddress);
            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
                    generateMacAddress(nextHopAddress),
                    egressConnectPoint);
            intentService.submit(TestIntentServiceHelper.eqExceptId(intent));
            expectLastCall().andAnswer(new IAnswer<Object>() {
                @Override
                public Object answer() throws Throwable {
                    installCount.countDown();
                    return null;
                }
            }).once();
            intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent));
            expectLastCall().andAnswer(new IAnswer<Object>() {
                @Override
                public Object answer() throws Throwable {
                    deleteCount.countDown();
                    return null;
                }
            }).once();
        }

        replay(intentService);

        intentSynchronizer.leaderChanged(true);
        TestUtils.setField(intentSynchronizer, "isActivatedLeader", true);

        // Send the add updates first
        router.processRouteUpdates(routeUpdates);

        // Give some time to let the intents be submitted
        installCount.await(5000, TimeUnit.MILLISECONDS);

        // Send the DELETE updates
        List<RouteUpdate> deleteRouteUpdates = new ArrayList<>();
        for (RouteUpdate update : routeUpdates) {
            RouteUpdate deleteUpdate = new RouteUpdate(RouteUpdate.Type.DELETE,
                                                       update.routeEntry());
            deleteRouteUpdates.add(deleteUpdate);
        }
        router.processRouteUpdates(deleteRouteUpdates);

        deleteCount.await(5000, TimeUnit.MILLISECONDS);

        assertEquals(0, router.getRoutes().size());
        assertEquals(0, intentSynchronizer.getRouteIntents().size());
        verify(intentService);
    }

    /**
     * This methods generates random route updates.
     *
     * @param numRoutes the number of route updates to generate
     * @return a list of route update
     */
    private List<RouteUpdate> generateRouteUpdates(int numRoutes) {
        List<RouteUpdate> routeUpdates = new ArrayList<>(numRoutes);

        Set<Ip4Prefix> prefixes = new HashSet<>();

        for (int i = 0; i < numRoutes; i++) {
            Ip4Prefix prefix;
            do {
                // Generate a random prefix length between MIN_PREFIX_LENGTH
                // and MAX_PREFIX_LENGTH
                int prefixLength = random.nextInt(
                        (MAX_PREFIX_LENGTH - MIN_PREFIX_LENGTH) + 1)
                        + MIN_PREFIX_LENGTH;
                prefix =
                    Ip4Prefix.valueOf(Ip4Address.valueOf(random.nextInt()),
                                      prefixLength);
                // We have to ensure we don't generate the same prefix twice
                // (this is quite easy to happen with small prefix lengths).
            } while (prefixes.contains(prefix));

            prefixes.add(prefix);

            // Randomly select a peer to use as the next hop
            BgpPeer nextHop = null;
            int peerNumber = random.nextInt(sdnIpConfigService.getBgpPeers()
                    .size());
            int j = 0;
            for (BgpPeer peer : sdnIpConfigService.getBgpPeers().values()) {
                if (j++ == peerNumber) {
                    nextHop = peer;
                    break;
                }
            }

            assertNotNull(nextHop);

            RouteUpdate update =
                new RouteUpdate(RouteUpdate.Type.UPDATE,
                        new RouteEntry(prefix,
                                       nextHop.ipAddress().getIp4Address()));

            routeUpdates.add(update);
        }

        return routeUpdates;
    }

    /**
     * Generates the MultiPointToSinglePointIntent that should be
     * submitted/withdrawn for a particular RouteUpdate.
     *
     * @param update the RouteUpdate to generate an intent for
     * @param nextHopMac a MAC address to use as the dst-mac for the intent
     * @param egressConnectPoint the outgoing ConnectPoint for the intent
     * @return the generated intent
     */
    private MultiPointToSinglePointIntent getIntentForUpdate(RouteUpdate update,
            MacAddress nextHopMac, ConnectPoint egressConnectPoint) {
        IpPrefix ip4Prefix = update.routeEntry().prefix();

        TrafficSelector.Builder selectorBuilder =
                DefaultTrafficSelector.builder();

        selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(ip4Prefix);

        TrafficTreatment.Builder treatmentBuilder =
                DefaultTrafficTreatment.builder();
        treatmentBuilder.setEthDst(nextHopMac);

        Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
        for (Interface intf : interfaceService.getInterfaces()) {
            if (!intf.connectPoint().equals(egressConnectPoint)) {
                ConnectPoint srcPort = intf.connectPoint();
                ingressPoints.add(srcPort);
            }
        }

        MultiPointToSinglePointIntent intent =
                new MultiPointToSinglePointIntent(APPID,
                selectorBuilder.build(), treatmentBuilder.build(),
                ingressPoints, egressConnectPoint);

        return intent;
    }

    /**
     * Generates a MAC address based on an IP address.
     * For the test we need MAC addresses but the actual values don't have any
     * meaning, so we'll just generate them based on the IP address. This means
     * we have a deterministic mapping from IP address to MAC address.
     *
     * @param ipAddress IP address used to generate a MAC address
     * @return generated MAC address
     */
    static MacAddress generateMacAddress(IpAddress ipAddress) {
        byte[] macAddress = new byte[MAC_ADDRESS_LENGTH];
        ByteBuffer bb = ByteBuffer.wrap(macAddress);

        // Put the IP address bytes into the lower four bytes of the MAC
        // address. Leave the first two bytes set to 0.
        bb.position(2);
        bb.put(ipAddress.toOctets());

        return MacAddress.valueOf(bb.array());
    }

    /**
     * Finds out the ConnectPoint for a BGP peer address.
     *
     * @param bgpPeerAddress the BGP peer address.
     */
    private ConnectPoint getConnectPoint(IpAddress bgpPeerAddress) {
        ConnectPoint connectPoint = null;

        for (BgpPeer bgpPeer: bgpPeers.values()) {
            if (bgpPeer.ipAddress().equals(bgpPeerAddress)) {
                connectPoint = bgpPeer.connectPoint();
                break;
            }
        }
        return connectPoint;
    }
}
