package net.onrc.onos.api.rest;

import com.codahale.metrics.Counter;
import net.onrc.onos.core.metrics.OnosMetrics;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
import org.restlet.resource.ClientResource;

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

/**
 * Unit tests for REST APIs for Counter Metrics.
 */
public class TestRestMetricsCounters extends TestRestMetrics {

    //  Test Counter data objects
    private static final OnosMetrics.MetricsComponent COMPONENT =
            OnosMetrics.registerComponent("MetricsUnitTests");
    private static final OnosMetrics.MetricsFeature FEATURE =
            COMPONENT.registerFeature("Counters");

    private static final String COUNTER1_NAME = "COUNTER1";
    private static final String COUNTER1_FULL_NAME = OnosMetrics.generateName(COMPONENT,
                                                     FEATURE,
                                                     COUNTER1_NAME);
    private static final int COUNTER1_COUNT = 0;

    private static final String COUNTER2_NAME = "COUNTER2";
    private static final String COUNTER2_FULL_NAME = OnosMetrics.generateName(COMPONENT,
                                                     FEATURE,
                                                     COUNTER2_NAME);
    private static final int COUNTER2_COUNT = -1;

    private static final String COUNTER3_NAME = "COUNTER3";
    private static final String COUNTER3_FULL_NAME = OnosMetrics.generateName(COMPONENT,
                                                     FEATURE,
                                                     COUNTER3_NAME);
    private static final int COUNTER3_COUNT = 5;

    private final Counter counter1 =
            OnosMetrics.createCounter(COMPONENT,
                                      FEATURE,
                                      COUNTER1_NAME);
    private final Counter counter2 =
            OnosMetrics.createCounter(COMPONENT,
                                      FEATURE,
                                      COUNTER2_NAME);
    private final Counter counter3 =
            OnosMetrics.createCounter(COMPONENT,
                                      FEATURE,
                                      COUNTER3_NAME);

    /**
     * Create some test data for the tests.
     */
    private void fillCounters() {
        counter1.inc(COUNTER1_COUNT);
        counter2.inc(COUNTER2_COUNT);
        counter3.inc(COUNTER3_COUNT);
    }

    /**
     * Check that a Counter object has the right contents.
     *
     * @param counterContainer JSON for the Counter
     * @param name name of the Counter
     * @param count expected count for the Counter
     * @throws JSONException if any of the JSON fetches fail
     */
    private void checkCounter(final JSONObject counterContainer,
                              final String name,
                              final int count) throws JSONException {
        final String counterName = counterContainer.getString("name");
        assertThat(counterName, is(notNullValue()));
        assertThat(counterName, is(equalTo(name)));

        final JSONObject counterObject = counterContainer.getJSONObject("counter");
        assertThat(counterObject, is(notNullValue()));

        final int counterValue = counterObject.getInt("count");
        assertThat(counterValue, is(equalTo(count)));
    }

    /**
     * Test the REST APIs for Metrics Counter objects.
     *
     * @throws JSONException if JSON processing fails
     */
    @Test
    public void testCounters() throws JSONException {

        fillCounters();

        //  Read the metrics from the REST API for the test data
        final ClientResource client = new ClientResource(getBaseRestMetricsUrl());

        final JSONObject metrics = getJSONObject(client);
        assertThat(metrics.length(), is(equalTo(5)));

        //  There should be 3 counters
        final JSONArray counters = metrics.getJSONArray("counters");
        assertThat(counters, is(notNullValue()));
        assertThat(counters.length(), is(3));

        //  There should be no timers, gauges, meters or histograms
        checkEmptyLists(metrics, "timers", "gauges", "meters", "histograms");

        //  Check the values for counter 1
        final JSONObject counter1Container = counters.getJSONObject(0);
        checkCounter(counter1Container, COUNTER1_FULL_NAME, COUNTER1_COUNT);

        //  Check the values for counter 1
        final JSONObject counter2Container = counters.getJSONObject(1);
        checkCounter(counter2Container, COUNTER2_FULL_NAME, COUNTER2_COUNT);

        //  Check the values for counter 1
        final JSONObject counter3Container = counters.getJSONObject(2);
        checkCounter(counter3Container, COUNTER3_FULL_NAME, COUNTER3_COUNT);

    }

}
