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

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import org.onlab.util.DataRateUnit;
import org.onosproject.incubator.net.resource.label.LabelResourceId;
import org.onosproject.incubator.net.tunnel.TunnelId;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DeviceId;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.intent.constraint.BandwidthConstraint;
import org.onosproject.net.Link;
import org.onosproject.net.PortNumber;
import org.onosproject.net.resource.ResourceConsumer;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.pce.pceservice.TunnelConsumerId;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.service.TestStorageService;

/**
 * Unit tests for DistributedPceStore class.
 */
public class DistributedPceStoreTest {

    private DistributedPceStore distrPceStore;
    private DeviceId deviceId1 = DeviceId.deviceId("foo");
    private DeviceId deviceId2 = DeviceId.deviceId("goo");
    private DeviceId deviceId3 = DeviceId.deviceId("yaa");
    private DeviceId deviceId4 = DeviceId.deviceId("zoo");
    private LabelResourceId labelId1 = LabelResourceId.labelResourceId(1);
    private LabelResourceId labelId2 = LabelResourceId.labelResourceId(2);
    private LabelResourceId labelId3 = LabelResourceId.labelResourceId(3);
    private LabelResourceId labelId4 = LabelResourceId.labelResourceId(4);
    private PortNumber portNumber1 = PortNumber.portNumber(1);
    private PortNumber portNumber2 = PortNumber.portNumber(2);
    private PortNumber portNumber3 = PortNumber.portNumber(3);
    private PortNumber portNumber4 = PortNumber.portNumber(4);
    private ConnectPoint srcConnectionPoint1 = new ConnectPoint(deviceId1, portNumber1);
    private ConnectPoint dstConnectionPoint2 = new ConnectPoint(deviceId2, portNumber2);
    private ConnectPoint srcConnectionPoint3 = new ConnectPoint(deviceId3, portNumber3);
    private ConnectPoint dstConnectionPoint4 = new ConnectPoint(deviceId4, portNumber4);
    private Link link1;
    private Link link2;
    private TunnelId tunnelId1 = TunnelId.valueOf("1");
    private TunnelId tunnelId2 = TunnelId.valueOf("2");
    private TunnelId tunnelId3 = TunnelId.valueOf("3");
    private TunnelId tunnelId4 = TunnelId.valueOf("4");
    private ResourceConsumer tunnelConsumerId1 = TunnelConsumerId.valueOf(10);
    private ResourceConsumer tunnelConsumerId2 = TunnelConsumerId.valueOf(20);
    private PcePathInfo failedPathInfo1;
    private PcePathInfo failedPathInfo2;
    private PcePathInfo failedPathInfo3;
    private PcePathInfo failedPathInfo4;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {
       distrPceStore = new DistributedPceStore();

       // Initialization of member variables
       link1 = DefaultLink.builder()
                          .providerId(new ProviderId("eth", "1"))
                          .annotations(DefaultAnnotations.builder().set("key1", "yahoo").build())
                          .src(srcConnectionPoint1)
                          .dst(dstConnectionPoint2)
                          .type(Link.Type.DIRECT)
                          .state(Link.State.ACTIVE)
                          .build();
       link2 = DefaultLink.builder()
                          .providerId(new ProviderId("mac", "2"))
                          .annotations(DefaultAnnotations.builder().set("key2", "google").build())
                          .src(srcConnectionPoint3)
                          .dst(dstConnectionPoint4)
                          .type(Link.Type.DIRECT)
                          .state(Link.State.ACTIVE)
                          .build();

       // Creates failedPathInfo1
       DeviceId src1 = DeviceId.deviceId("foo1");
       DeviceId dst1 = DeviceId.deviceId("goo1");
       String name1 = "pcc1";
       LspType lspType1 = LspType.SR_WITHOUT_SIGNALLING;
       List<Constraint> constraints1 = new LinkedList<>();
       Constraint bandwidth1 = BandwidthConstraint.of(200, DataRateUnit.BPS);
       constraints1.add(bandwidth1);

       failedPathInfo1 = new PcePathInfo(src1, dst1, name1, constraints1, lspType1, null);

       // Creates failedPathInfo2
       DeviceId src2 = DeviceId.deviceId("foo2");
       DeviceId dst2 = DeviceId.deviceId("goo2");
       String name2 = "pcc2";
       LspType lspType2 = LspType.SR_WITHOUT_SIGNALLING;
       List<Constraint> constraints2 = new LinkedList<>();
       Constraint bandwidth2 = BandwidthConstraint.of(400, DataRateUnit.BPS);
       constraints2.add(bandwidth2);

       failedPathInfo2 = new PcePathInfo(src2, dst2, name2, constraints2, lspType2, null);

       // Creates failedPathInfo3
       DeviceId src3 = DeviceId.deviceId("foo3");
       DeviceId dst3 = DeviceId.deviceId("goo3");
       String name3 = "pcc3";
       LspType lspType3 = LspType.SR_WITHOUT_SIGNALLING;
       List<Constraint> constraints3 = new LinkedList<>();
       Constraint bandwidth3 = BandwidthConstraint.of(500, DataRateUnit.BPS);
       constraints3.add(bandwidth3);

       failedPathInfo3 = new PcePathInfo(src3, dst3, name3, constraints3, lspType3, null);

       // Creates failedPathInfo4
       DeviceId src4 = DeviceId.deviceId("foo4");
       DeviceId dst4 = DeviceId.deviceId("goo4");
       String name4 = "pcc4";
       LspType lspType4 = LspType.SR_WITHOUT_SIGNALLING;
       List<Constraint> constraints4 = new LinkedList<>();
       Constraint bandwidth4 = BandwidthConstraint.of(600, DataRateUnit.BPS);
       constraints4.add(bandwidth4);

       failedPathInfo4 = new PcePathInfo(src4, dst4, name4, constraints4, lspType4, null);
    }

    @After
    public void tearDown() throws Exception {
    }

    /**
     * Checks the operation of addTunnelInfo() method.
     */
    @Test
    public void testAddTunnelInfo() {
        // initialization
        distrPceStore.storageService = new TestStorageService();
        distrPceStore.activate();

        // TunnelId with device label store information
        distrPceStore.addTunnelInfo(tunnelId1, tunnelConsumerId1);
        assertThat(distrPceStore.existsTunnelInfo(tunnelId1), is(true));
        assertThat(distrPceStore.getTunnelInfo(tunnelId1), is(tunnelConsumerId1));
        distrPceStore.addTunnelInfo(tunnelId2, tunnelConsumerId2);
        assertThat(distrPceStore.existsTunnelInfo(tunnelId2), is(true));
        assertThat(distrPceStore.getTunnelInfo(tunnelId2), is(tunnelConsumerId2));
    }

    /**
     * Checks the operation of addFailedPathInfo() method.
     */
    @Test
    public void testAddFailedPathInfo() {
        // initialization
        distrPceStore.storageService = new TestStorageService();
        distrPceStore.activate();

        // PcePathInfo with pce path input information
        distrPceStore.addFailedPathInfo(failedPathInfo1);
        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo1), is(true));
        distrPceStore.addFailedPathInfo(failedPathInfo2);
        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo2), is(true));
    }

    /**
     * Checks the operation of existsTunnelInfo() method.
     */
    @Test
    public void testExistsTunnelInfo() {
        testAddTunnelInfo();

        assertThat(distrPceStore.existsTunnelInfo(tunnelId1), is(true));
        assertThat(distrPceStore.existsTunnelInfo(tunnelId2), is(true));
        assertThat(distrPceStore.existsTunnelInfo(tunnelId3), is(false));
        assertThat(distrPceStore.existsTunnelInfo(tunnelId4), is(false));
    }

    /**
     * Checks the operation of existsFailedPathInfo() method.
     */
    @Test
    public void testExistsFailedPathInfo() {
        testAddFailedPathInfo();

        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo1), is(true));
        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo2), is(true));
        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo3), is(false));
        assertThat(distrPceStore.existsFailedPathInfo(failedPathInfo4), is(false));
    }

    /**
     * Checks the operation of getTunnelInfoCount() method.
     */
    @Test
    public void testGetTunnelInfoCount() {
        testAddTunnelInfo();

        assertThat(distrPceStore.getTunnelInfoCount(), is(2));
    }

    /**
     * Checks the operation of getFailedPathInfoCount() method.
     */
    @Test
    public void testGetFailedPathInfoCount() {
        testAddFailedPathInfo();

        assertThat(distrPceStore.getFailedPathInfoCount(), is(2));
    }

    /**
     * Checks the operation of getTunnelInfos() method.
     */
    @Test
    public void testGetTunnelInfos() {
        testAddTunnelInfo();

        Map<TunnelId, ResourceConsumer> tunnelInfoMap = distrPceStore.getTunnelInfos();
        assertThat(tunnelInfoMap, is(notNullValue()));
        assertThat(tunnelInfoMap.isEmpty(), is(false));
        assertThat(tunnelInfoMap.size(), is(2));
    }

    /**
     * Checks the operation of getFailedPathInfos() method.
     */
    @Test
    public void testGetFailedPathInfos() {
        testAddFailedPathInfo();

        Iterable<PcePathInfo> failedPathInfoSet = distrPceStore.getFailedPathInfos();
        assertThat(failedPathInfoSet, is(notNullValue()));
        assertThat(failedPathInfoSet.iterator().hasNext(), is(true));
    }

    /**
     * Checks the operation of getTunnelInfo() method.
     */
    @Test
    public void testGetTunnelInfo() {
        testAddTunnelInfo();

        // tunnelId1 with device label store info
        assertThat(tunnelId1, is(notNullValue()));
        assertThat(distrPceStore.getTunnelInfo(tunnelId1), is(tunnelConsumerId1));

        // tunnelId2 with device label store info
        assertThat(tunnelId2, is(notNullValue()));
        assertThat(distrPceStore.getTunnelInfo(tunnelId2), is(tunnelConsumerId2));
    }

    /**
     * Checks the operation of removeTunnelInfo() method.
     */
    @Test
    public void testRemoveTunnelInfo() {
        testAddTunnelInfo();

        assertThat(distrPceStore.removeTunnelInfo(tunnelId1), is(true));
        assertThat(distrPceStore.removeTunnelInfo(tunnelId2), is(true));
    }

    /**
     * Checks the operation of removeFailedPathInfo() method.
     */
    @Test
    public void testRemoveFailedPathInfo() {
        testAddFailedPathInfo();

        assertThat(distrPceStore.removeFailedPathInfo(failedPathInfo1), is(true));
        assertThat(distrPceStore.removeFailedPathInfo(failedPathInfo2), is(true));
        assertThat(distrPceStore.removeFailedPathInfo(failedPathInfo3), is(false));
        assertThat(distrPceStore.removeFailedPathInfo(failedPathInfo4), is(false));
    }
}
