// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/cobalt/cpp/metric_event_builder.h"

#include <gtest/gtest.h>

namespace cobalt {

using fuchsia::metrics::MetricEvent;

const uint32_t kMetricId = 123;
const uint32_t kDimension1 = 456;
const uint32_t kDimension2 = 789;

TEST(MetricEventBuilder, OccurrenceEvent) {
  uint64_t count = 100;

  MetricEvent event;
  event.metric_id = kMetricId;
  event.payload.set_count(count);

  ASSERT_TRUE(fidl::Equals(event, MetricEventBuilder(kMetricId).as_occurrence(count)));
}

TEST(MetricEventBuilder, IntegerEvent) {
  int64_t integer_value = 5678;

  MetricEvent event;
  event.metric_id = kMetricId;
  event.event_codes.push_back(kDimension1);
  event.event_codes.push_back(kDimension2);
  event.payload.set_integer_value(integer_value);

  ASSERT_TRUE(fidl::Equals(event, MetricEventBuilder(kMetricId)
                                      .with_event_codes({kDimension1, kDimension2})
                                      .as_integer(integer_value)));
}

TEST(MetricEventBuilder, IntegerHistogram) {
  std::vector<fuchsia::metrics::HistogramBucket> histogram;
  histogram.push_back({0, 10});
  histogram.push_back({1, 20});
  histogram.push_back({2, 30});
  histogram.push_back({3, 40});

  MetricEvent event;
  event.metric_id = kMetricId;
  event.event_codes.push_back(kDimension1);
  event.event_codes.push_back(kDimension2);
  event.payload.set_histogram(histogram);

  ASSERT_TRUE(fidl::Equals(event, MetricEventBuilder(kMetricId)
                                      .with_event_codes({kDimension1, kDimension2})
                                      .as_integer_histogram(histogram)));
}

TEST(MetricEventBuilder, StringEvent) {
  std::string string_value = "test-string";

  MetricEvent event;
  event.metric_id = kMetricId;
  event.event_codes.push_back(kDimension1);
  event.event_codes.push_back(kDimension2);
  event.payload.set_string_value(string_value);

  ASSERT_TRUE(fidl::Equals(event, MetricEventBuilder(kMetricId)
                                      .with_event_codes({kDimension1, kDimension2})
                                      .as_string(string_value)));
}

TEST(MetricEventBuilder, Clone) {
  uint64_t integer_value = 5678;
  auto b = std::move(MetricEventBuilder(kMetricId).with_event_codes({kDimension1, kDimension2}));

  ASSERT_FALSE(fidl::Equals(b.as_integer(integer_value), b.as_integer(integer_value)));

  auto b2 = std::move(MetricEventBuilder(kMetricId).with_event_codes({kDimension1, kDimension2}));

  ASSERT_TRUE(fidl::Equals(b2.Clone().as_integer(integer_value), b2.as_integer(integer_value)));
}

TEST(MetricEventBuilder, event_code_at) {
  uint64_t integer_value = 5678;
  ASSERT_TRUE(fidl::Equals(MetricEventBuilder(kMetricId)
                               .with_event_codes({kDimension1, kDimension2})
                               .as_integer(integer_value),
                           MetricEventBuilder(kMetricId)
                               .with_event_code_at(1, kDimension2)
                               .with_event_code_at(0, kDimension1)
                               .as_integer(integer_value)));
}

}  // namespace cobalt
