// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.metricsproxy.service;

import ai.vespa.metricsproxy.TestUtil;
import ai.vespa.metricsproxy.metric.Metric;
import ai.vespa.metricsproxy.metric.Metrics;
import org.junit.Test;

import java.io.IOException;

import static ai.vespa.metricsproxy.metric.model.MetricId.toMetricId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

/**
 */
public class MetricsFetcherTest {

    private static final int port = 9;  //port number is not used in this test

    private static class MetricsConsumer implements MetricsParser.Consumer {
        Metrics metrics = new Metrics();
        @Override
        public void consume(Metric metric) {
            metrics.add(metric);
        }
    }
    Metrics fetch(String data) throws IOException {
        RemoteMetricsFetcher fetcher = new RemoteMetricsFetcher(new DummyService(0, "dummy/id/0"), port);
        MetricsConsumer consumer = new MetricsConsumer();
        fetcher.createMetrics(data, consumer, 0);
        return consumer.metrics;
    }

    @Test
    public void testStateFormatMetricsParse() throws IOException {
        String jsonData = TestUtil.getFileContents("metrics-state.json");
        Metrics metrics = fetch(jsonData);
        assertEquals(10, metrics.size());
        assertEquals(28, getMetric("query_hits.count", metrics).getValue());
        assertEquals(0.4667, getMetric("queries.rate", metrics).getValue());
        assertEquals(1334134700L, metrics.getTimeStamp());
    }

    @Test
    public void testEmptyJson() throws IOException {
        String  jsonData = "{}";
        Metrics metrics = fetch(jsonData);
        assertEquals(0, metrics.size());
    }

    @Test
    public void testErrors() throws IOException {
        String jsonData;
        Metrics metrics = null;

        jsonData = "";
        try {
            metrics = fetch(jsonData);
            fail("Should have an IOException instead");
        } catch (IOException e) {
            assertEquals("Expected start of object, got null", e.getMessage());
        }
        assertNull(metrics);

        jsonData = "{\n" +
                "\"status\" : {\n" +
                "  \"code\" : \"up\",\n" +
                "  \"message\" : \"Everything ok here\"\n" +
                "}\n" +
                "}";
        metrics = fetch(jsonData);
        assertEquals(0, metrics.size());

        jsonData = "{\n" +
                "\"status\" : {\n" +
                "  \"code\" : \"up\",\n" +
                "  \"message\" : \"Everything ok here\"\n" +
                "},\n" +
                "\"metrics\" : {\n" +
                "  \"snapshot\" : {\n" +
                "    \"from\" : 1334134640.089,\n" +
                "    \"to\" : 1334134700.088\n" +
                "  },\n" +
                "  \"values\" : [\n" +
                "   {\n" +
                "     \"name\" : \"queries\",\n" +
                "     \"description\" : \"Number of queries executed during snapshot interval\",\n" +
                "     \"values\" : {\n" +
                "       \"count\" : null,\n" +
                "       \"rate\" : 0.4667\n" +
                "     },\n" +
                "     \"dimensions\" : {\n" +
                "      \"searcherid\" : \"x\"\n" +
                "     }\n" +
                "   }\n" + "" +
                " ]\n" +
                "}\n" +
                "}";

        metrics = null;
        try {
            metrics = fetch(jsonData);
            fail("Should have an IOException instead");
        } catch (IllegalArgumentException e) {
            assertEquals("Value for aggregator 'count' is not a number", e.getMessage());
        }
        assertNull(metrics);
    }

    public Metric getMetric(String metric, Metrics metrics) {
        for (Metric m: metrics.list()) {
            if (m.getName().equals(toMetricId(metric)))
                return m;
        }
        return null;
    }

}

@@ -477,16 +477,59 @@
 rtNull;%0A
+import static org.junit.Assert.assertTrue;%0A
 import s
@@ -1852,32 +1852,1009 @@
 size());%0A    %7D%0A%0A
+    @Test%0A    public void testSkippingNullDimensions() throws IOException %7B%0A        String jsonData =%0A                %22%7B%5C%22status%5C%22 : %7B%5C%22code%5C%22 : %5C%22up%5C%22,%5C%22message%5C%22 : %5C%22Everything ok here%5C%22%7D,%22 +%0A                %22%5C%22metrics%5C%22 : %7B%5C%22snapshot%5C%22 : %7B%5C%22from%5C%22 : 1334134640.089,%5C%22to%5C%22 : 1334134700.088%22 + %22  %7D,%22 +%0A                %22%5C%22values%5C%22 : %5B%22 +%0A                %22%7B%22 +%0A                %22      %5C%22name%5C%22 : %5C%22some.bogus.metric%5C%22,%22 +%0A                %22      %5C%22values%5C%22 : %7B%22 +%0A                %22        %5C%22count%5C%22 : 12,%22 +%0A                %22        %5C%22rate%5C%22 : 0.2%22 +%0A                %22      %7D,%22 +%0A                %22      %5C%22dimensions%5C%22 : %7B%22 +%0A                %22        %5C%22version%5C%22 : null%22 +%0A                %22      %7D%22 +%0A                %22    %7D%22 +%0A                %22%5D%7D%7D%22;%0A%0A        Metrics metrics = fetch(jsonData);%0A        assertEquals(2, metrics.size());%0A        assertTrue(metrics.list().get(0).getDimensions().isEmpty());%0A        assertTrue(metrics.list().get(1).getDimensions().isEmpty());%0A    %7D%0A%0A
     @Test%0A    pu

Add test for dimensions incorrectly containing null