

package com.rackspacecloud.blueflood.io.serializers;

import com.rackspacecloud.blueflood.types.*;
import com.rackspacecloud.blueflood.utils.TimeValue;
import junit.framework.Assert;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class IMetricSerializerTest {
    static final Locator goneIn = Locator.createLocatorFromPathComponents("gone", "in");
    static final TimeValue sixtySeconds = new TimeValue(60l, TimeUnit.SECONDS);
    static final ObjectMapper mapper = new IMetricSerializer().getObjectMapper();
    private static final String START_STRING = "{\"class\":\"preaggregated\",\"collectionTime\":12345,\"tenantId\":\"gone\",\"metricName\":\"in\",\"metricValue\":{\"type\":\"";
    private static final String END_STRING = "},\"ttlInSeconds\":60}";

    @Test
    public void testCounterSerialization() throws IOException {
        String counterValue = "{\"type\":\"counter\",\"count\":1,\"rate\":0.06666666666666667,\"sampleCount\":0}";

        CounterRollup counterDeserialized = mapper.readValue(counterValue, CounterRollup.class);
        String counterSerialized = mapper.writeValueAsString(counterDeserialized);
        Assert.assertEquals(counterValue, counterSerialized);

        CounterRollup counterReserialized = mapper.readValue(counterSerialized, CounterRollup.class);
        Assert.assertEquals(counterDeserialized, counterReserialized);

        PreaggregatedMetric m = new PreaggregatedMetric(12345l, goneIn, sixtySeconds, counterReserialized);
        String preagg = mapper.writeValueAsString(m);
        Assert.assertTrue(preagg, preagg.startsWith(START_STRING));
        Assert.assertTrue(preagg, preagg.endsWith(END_STRING));
    }

    @Test
    public void testGaugeSerialization() throws IOException {
        String gaugeValue = "{\"type\":\"gauge\",\"count\":1,\"latestNumericValue\":397,\"max\":397,\"mean\":397,\"min\":397,\"timestamp\":1389211230,\"var\":0.0}";

        GaugeRollup gaugeDeserialized = mapper.readValue(gaugeValue, GaugeRollup.class);
        String gaugeSerialized = mapper.writeValueAsString(gaugeDeserialized);
        Assert.assertEquals(gaugeValue, gaugeSerialized);

        GaugeRollup gaugeReserialized = mapper.readValue(gaugeSerialized, GaugeRollup.class);
        Assert.assertEquals(gaugeDeserialized, gaugeReserialized);

        PreaggregatedMetric m = new PreaggregatedMetric(12345l, goneIn, sixtySeconds, gaugeReserialized);
        String preagg = mapper.writeValueAsString(m);
        Assert.assertTrue(preagg, preagg.startsWith(START_STRING));
        Assert.assertTrue(preagg, preagg.endsWith(END_STRING));
    }

    @Test
    public void testSetSerialization() throws IOException {
        String setValue = "{\"type\":\"set\",\"count\":9,\"hashes\":[746007989,1875251108,98262,103159993,1727114331,-1034140067,98699,1062516268,99644]}";

        SetRollup setDeserialized = mapper.readValue(setValue, SetRollup.class);
        String setSerialized = mapper.writeValueAsString(setDeserialized);
        Assert.assertEquals(setValue, setSerialized);

        SetRollup setReserialized = mapper.readValue(setSerialized, SetRollup.class);
        Assert.assertEquals(setDeserialized, setReserialized);

        PreaggregatedMetric m = new PreaggregatedMetric(12345l, goneIn, sixtySeconds, setReserialized);
        String preagg = mapper.writeValueAsString(m);
        Assert.assertTrue(preagg, preagg.startsWith(START_STRING));
        Assert.assertTrue(preagg, preagg.endsWith(END_STRING));
    }

    @Test
    public void testTimerSerialization() throws IOException {
        String timerValue = "{\"type\":\"timer\",\"average\":214,\"count\":1,\"max\":214,\"min\":214,\"percentiles\":{\"98\":214,\"99\":214,\"75\":214,\"999\":214,\"50\":214},\"rate\":0.06666666666666667,\"sampleCount\":1,\"sum\":214,\"variance\":0.0}";

        TimerRollup timerDeserialized = mapper.readValue(timerValue, TimerRollup.class);
        String timerSerialized = mapper.writeValueAsString(timerDeserialized);
        Assert.assertEquals(timerValue, timerSerialized);

        TimerRollup timerReserialized = mapper.readValue(timerSerialized, TimerRollup.class);
        Assert.assertEquals(timerDeserialized, timerReserialized);

        PreaggregatedMetric m = new PreaggregatedMetric(12345l, goneIn, sixtySeconds, timerReserialized);
        String preagg = mapper.writeValueAsString(m);
        Assert.assertTrue(preagg, preagg.startsWith(START_STRING));
        Assert.assertTrue(preagg, preagg.endsWith(END_STRING));
    }

    @Test
    public void testRawSerialization() throws IOException {
        Metric metric = new Metric(goneIn, 5, 12345l, sixtySeconds, "bytes");
        String serialized = mapper.writeValueAsString(metric);

        Metric deserialized = mapper.readValue(serialized, Metric.class);
        String reserialized = mapper.writeValueAsString(deserialized);
        Assert.assertEquals(metric, deserialized);
        Assert.assertEquals(serialized, reserialized);
    }
}