/*
 * Copyright 2016 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.sdxl3;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
import org.onosproject.sdxl3.config.SdxProvidersConfig;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertFalse;

public class SdxProvidersConfigTest {
    private static final ApplicationId APP_ID =
            new TestApplicationId(SdxL3.SDX_L3_APP);
    private static final String KEY = "key";

    private static final String NAME1 = "peer1";
    private static final String IP_STRING1 = "10.0.1.1";
    private static final IpAddress IP1 = IpAddress.valueOf(IP_STRING1);
    private static final String PORT_STRING1 = "of:00000000000000a1/1";
    private static final ConnectPoint PORT1 =
            ConnectPoint.deviceConnectPoint(PORT_STRING1);
    private static final String INTF_NAME1 = "conn_point1";

    private static final String IP_STRING2 = "10.0.2.1";
    private static final IpAddress IP2 = IpAddress.valueOf(IP_STRING2);
    private static final String PORT_STRING2 = "of:00000000000000a1/2";
    private static final ConnectPoint PORT2 =
            ConnectPoint.deviceConnectPoint(PORT_STRING2);
    private static final String INTF_NAME2 = "conn_point2";

    private static final String NAME3 = "new_peer";
    private static final String IP_STRING3 = "10.0.3.1";
    private static final String PORT_STRING3 = "of:00000000000000a1/3";
    private static final ConnectPoint PORT3 =
            ConnectPoint.deviceConnectPoint(PORT_STRING3);
    private static final IpAddress IP3 = IpAddress.valueOf(IP_STRING3);
    private static final String INTF_NAME3 = "conn_point3";

    private static final String JSON_TREE = "{\"" + SdxProvidersConfig.PEERS + "\"" +
            ": [{\"" + SdxProvidersConfig.NAME + "\" : \"" + NAME1 + "\", " +
            "\"" + SdxProvidersConfig.IP + "\" : \"" + IP_STRING1 + "\", " +
            "\"" + SdxProvidersConfig.CONN_POINT + "\" : \"" + PORT_STRING1 + "\", " +
            "\"" + SdxProvidersConfig.INTF_NAME + "\" : \"" + INTF_NAME1 + "\"}, " +
            "{ \"" + SdxProvidersConfig.IP + "\" : \"" + IP_STRING2 + "\", " +
            "\"" + SdxProvidersConfig.CONN_POINT + "\" : \"" + PORT_STRING2 + "\", " +
            "\"" + SdxProvidersConfig.INTF_NAME + "\" : \"" + INTF_NAME2 + "\"}]}";

    private static final String EMPTY_JSON_TREE = "{ }";

    private Set<SdxProvidersConfig.PeerConfig> peers = new HashSet<>();
    private SdxProvidersConfig.PeerConfig peer1;

    private SdxProvidersConfig peersConfig = new SdxProvidersConfig();
    private SdxProvidersConfig emptyPeersConfig = new SdxProvidersConfig();

    private final ConfigApplyDelegate delegate = new MockCfgDelegate();
    private final ObjectMapper mapper = new ObjectMapper();

    @Before
    public void setUp()  throws Exception {
        peers = createPeers();
        JsonNode node = new ObjectMapper().readTree(JSON_TREE);
        peersConfig.init(APP_ID, KEY, node, mapper, delegate);
        JsonNode emptyTree = new ObjectMapper().readTree(EMPTY_JSON_TREE);
        emptyPeersConfig.init(APP_ID, KEY, emptyTree, mapper, delegate);
    }

    /**
     * Tests if peers can be retrieved from JSON.
     */
    @Test
    public void testBgpPeers() throws Exception {
        assertEquals(peers, peersConfig.bgpPeers());
    }

    /**
     * Tests if interface name can be retrieved for given peer's IP.
     */
    @Test
    public void testGetInterfaceNameForPeer() throws Exception {
        assertEquals(INTF_NAME1, peersConfig.getInterfaceNameForPeer(IP1));
    }

    /**
     * Tests addition of new peer.
     */
    @Test
    public void testAddPeer() throws Exception {
        int initialSize = peersConfig.bgpPeers().size();
        SdxProvidersConfig.PeerConfig newPeer = createNewPeer();
        peersConfig.addPeer(newPeer);
        assertEquals(initialSize + 1, peersConfig.bgpPeers().size());
        peers.add(newPeer);
        assertEquals(peers, peersConfig.bgpPeers());
    }

    /**
     * Tests addition of new peer to empty configuration.
     */
    @Test
    public void testAddPeerToEmpty() throws Exception {
        emptyPeersConfig.addPeer(createNewPeer());
        assertFalse(emptyPeersConfig.bgpPeers().isEmpty());
    }

    /**
     * Tests getting peer configuration based on given name.
     */
    @Test
    public void testGetPeerForName() throws Exception {
        assertEquals(peer1, peersConfig.getPeerForName(Optional.of(NAME1)));
    }

    /**
     * Tests getting peer configuration based on given IP.
     */
    @Test
    public void testGetPeerForIp() throws Exception {
        assertEquals(peer1, peersConfig.getPeerForIp(IP1));
    }

    /**
     * Tests removing peer details based on given IP.
     */
    @Test
    public void testRemovePeer() throws Exception {
        int initialSize = peersConfig.bgpPeers().size();
        peersConfig.removePeer(IP1);
        assertEquals(initialSize - 1, peersConfig.bgpPeers().size());
        peers.remove(peer1);
        assertEquals(peers, peersConfig.bgpPeers());    }

    private Set<SdxProvidersConfig.PeerConfig> createPeers() {
        Set<SdxProvidersConfig.PeerConfig> peers = Sets.newHashSet();

        peer1 = new SdxProvidersConfig.
                PeerConfig(Optional.of(NAME1), IP1, PORT1, INTF_NAME1);
        peers.add(peer1);
        peers.add(new SdxProvidersConfig.
                PeerConfig(Optional.empty(), IP2, PORT2, INTF_NAME2));

        return peers;
    }

    private SdxProvidersConfig.PeerConfig createNewPeer() {
        return new SdxProvidersConfig.
                PeerConfig(Optional.of(NAME3), IP3, PORT3, INTF_NAME3);
    }

    private class MockCfgDelegate implements ConfigApplyDelegate {

        @Override
        public void onApply(@SuppressWarnings("rawtypes") Config config) {
            config.apply();
        }

    }
}

