/*
 * Copyright 2015 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.rest;

import java.util.HashMap;
import java.util.stream.IntStream;

import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.rest.BaseResource;
import org.onosproject.codec.CodecService;
import org.onosproject.codec.impl.CodecManager;
import org.onosproject.net.Link;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.statistic.DefaultLoad;
import org.onosproject.net.statistic.StatisticService;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.WebResource;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.onosproject.net.NetTestTools.connectPoint;
import static org.onosproject.net.NetTestTools.link;

/**
 * Unit tests for statistics REST APIs.
 */
public class StatisticsResourceTest extends ResourceTest {

    Link link1 = link("src1", 1, "dst1", 1);
    Link link2 = link("src2", 2, "dst2", 2);
    Link link3 = link("src3", 3, "dst3", 3);

    LinkService mockLinkService;
    StatisticService mockStatisticService;

    /**
     * Initializes test mocks and environment.
     */
    @Before
    public void setUpTest() {
        mockLinkService = createMock(LinkService.class);
        expect(mockLinkService.getLinks())
                .andReturn(ImmutableList.of(link1, link2, link3));
        expect(mockLinkService.getLinks(connectPoint("0000000000000001", 2)))
                .andReturn(ImmutableSet.of(link3));

        mockStatisticService = createMock(StatisticService.class);
        expect(mockStatisticService.load(link1))
                .andReturn(new DefaultLoad(2, 1, 1));
        expect(mockStatisticService.load(link2))
                .andReturn(new DefaultLoad(22, 11, 1));
        expect(mockStatisticService.load(link3))
                .andReturn(new DefaultLoad(222, 111, 1));

        replay(mockLinkService, mockStatisticService);

        // Register the services needed for the test
        CodecManager codecService = new CodecManager();
        codecService.activate();
        ServiceDirectory testDirectory =
                new TestServiceDirectory()
                        .add(LinkService.class, mockLinkService)
                        .add(StatisticService.class, mockStatisticService)
                        .add(CodecService.class, codecService);

        BaseResource.setServiceDirectory(testDirectory);
    }

    /**
     * Checks that the values in a JSON representation of a Load are
     * correct.
     *
     * @param load JSON for the Loan object
     * @param rate expected vale fo rate
     * @param latest expected value for latest
     * @param valid expected value for valid flag
     * @param device expected device ID
     */
    private void checkValues(JsonObject load, int rate, int latest,
                             boolean valid, String device) {
        assertThat(load, notNullValue());
        assertThat(load.get("rate").asInt(), is(rate));
        assertThat(load.get("latest").asInt(), is(latest));
        assertThat(load.get("valid").asBoolean(), is(valid));
        assertThat(load.get("time").asLong(),
                lessThanOrEqualTo((System.currentTimeMillis())));
        assertThat(load.get("link").asString(),
                containsString("device=of:" + device));
    }

    /**
     * Tests GET of a single Load statistics object.
     */
    @Test
    public void testSingleLoadGet() {
        final WebResource rs = resource();
        final String response = rs.path("statistics/flows/link")
                .queryParam("device", "of:0000000000000001")
                .queryParam("port", "2")
                .get(String.class);

        final JsonObject result = JsonObject.readFrom(response);
        assertThat(result, notNullValue());

        assertThat(result.names(), hasSize(1));
        assertThat(result.names().get(0), is("loads"));

        final JsonArray jsonLoads = result.get("loads").asArray();
        assertThat(jsonLoads, notNullValue());
        assertThat(jsonLoads.size(), is(1));

        JsonObject load1 = jsonLoads.get(0).asObject();
        checkValues(load1, 111, 222, true, "src3");
    }

    /**
     * Tests GET of all Load statistics objects.
     */
    @Test
    public void testLoadsGet() {
        final WebResource rs = resource();
        final String response = rs.path("statistics/flows/link/").get(String.class);

        final JsonObject result = JsonObject.readFrom(response);
        assertThat(result, notNullValue());

        assertThat(result.names(), hasSize(1));
        assertThat(result.names().get(0), is("loads"));

        final JsonArray jsonLoads = result.get("loads").asArray();
        assertThat(jsonLoads, notNullValue());
        assertThat(jsonLoads.size(), is(3));

        // Hash the loads by the current field to allow easy lookup if the
        // order changes.
        HashMap<Integer, JsonObject> currentMap = new HashMap<>();
        IntStream.range(0, jsonLoads.size())
                .forEach(index -> currentMap.put(
                        jsonLoads.get(index).asObject().get("latest").asInt(),
                        jsonLoads.get(index).asObject()));

        JsonObject load1 = currentMap.get(2);
        checkValues(load1, 1, 2, true, "src1");

        JsonObject load2 = currentMap.get(22);
        checkValues(load2, 11, 22, true, "src2");

        JsonObject load3 = currentMap.get(222);
        checkValues(load3, 111, 222, true, "src3");

    }
}
