// 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/logger/event_vector_index.h"

#include <gtest/gtest.h>

#include "src/registry/metric_definition.pb.h"

namespace cobalt::logger {

namespace {
std::string EventVectorAsString(const std::vector<uint32_t> &event_vector) {
  std::stringstream buf;
  buf << "{";
  for (uint32_t event_code : event_vector) {
    buf << event_code << ", ";
  }
  buf << "}";
  return buf.str();
}
}  // namespace

// Test GetNumEventCodes() when the metric dimension has no max_event_code and
// its enumerated event codes are consecutive.
TEST(GetNumEventCodesTest, ConsecutiveNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[0] = "dim_0";
  (*dimension.mutable_event_codes())[1] = "dim_1";
  (*dimension.mutable_event_codes())[2] = "dim_2";

  EXPECT_EQ(GetNumEventCodes(dimension), 3u);
}

// Test GetNumEventCodes() when the metric dimension has no max_event_code and
// its enumerated event codes are not consecutive.
TEST(GetNumEventCodesTest, NotConsecutiveNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[0] = "dim_0";
  (*dimension.mutable_event_codes())[100] = "dim_1";
  (*dimension.mutable_event_codes())[200] = "dim_2";

  EXPECT_EQ(GetNumEventCodes(dimension), 3u);
}

// Test GetNumEventCodes() when the metric dimension has a max_event_code.
TEST(GetNumEventCodesTest, MaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  dimension.set_max_event_code(10);
  (*dimension.mutable_event_codes())[1] = "dim_0";
  (*dimension.mutable_event_codes())[2] = "dim_1";

  EXPECT_EQ(GetNumEventCodes(dimension), 11u);
}

// Test GetNumEventVectors with MetricDimensions which have
// consecutive and non-consecutive event codes and max_event_code.
TEST(GetNumEventVectorsTest, AllDimensionTypes) {
  google::protobuf::RepeatedPtrField<MetricDefinition::MetricDimension> metric_dimensions;

  auto dimension = metric_dimensions.Add();
  dimension->set_dimension("dimension_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[1] = "dim_1";
  (*dimension->mutable_event_codes())[2] = "dim_2";

  dimension = metric_dimensions.Add();
  dimension->set_dimension("dimension_non_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[100] = "dim_1";
  (*dimension->mutable_event_codes())[200] = "dim_2";
  (*dimension->mutable_event_codes())[300] = "dim_3";

  dimension = metric_dimensions.Add();
  dimension->set_dimension("dimension_max_event_code");
  dimension->set_max_event_code(10);
  (*dimension->mutable_event_codes())[1] = "dim_0";
  (*dimension->mutable_event_codes())[2] = "dim_1";

  uint64_t expected = 132;

  EXPECT_EQ(GetNumEventVectors(metric_dimensions), expected);
}

// Test EventCodeToIndexForDimension() when the metric dimension has no
// max_event_code, its enumerated event codes are consecutive, and the supplied
// event code is valid. Also check that EventCodeFromIndexForDimension() gives
// us back the original event code.
TEST(EventCodeToIndexForDimensionTest, ConsecutiveNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[0] = "dim_0";
  (*dimension.mutable_event_codes())[1] = "dim_1";
  (*dimension.mutable_event_codes())[2] = "dim_2";

  uint32_t event_code = 1;
  uint64_t index = 1u;
  auto status_or_index = EventCodeToIndexForDimension(event_code, dimension);
  ASSERT_TRUE(status_or_index.ok());
  EXPECT_EQ(status_or_index.ValueOrDie(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.ValueOrDie(), event_code);
}

// Test EventCodeToIndexForDimension() when the metric dimension has no
// max_event_code, its enumerated event codes are not consecutive, and the
// supplied event code is valid. Also check that
// EventCodeFromIndexForDimension() gives us back the original event code.
TEST(EventCodeToIndexForDimensionTest, NotConsecutiveNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[0] = "dim_0";
  (*dimension.mutable_event_codes())[100] = "dim_1";
  (*dimension.mutable_event_codes())[200] = "dim_2";

  uint32_t event_code = 100;
  uint64_t index = 1u;
  auto status_or_index = EventCodeToIndexForDimension(event_code, dimension);
  ASSERT_TRUE(status_or_index.ok());
  EXPECT_EQ(status_or_index.ValueOrDie(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.ValueOrDie(), event_code);
}

// Test EventCodeToIndexForDimension() when the metric dimension has a
// max_event_code and the supplied event code is valid. Also check that
// EventCodeFromIndexForDimension() gives us back the original event code.
TEST(EventCodeToIndexForDimensionTest, MaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  dimension.set_max_event_code(10);
  (*dimension.mutable_event_codes())[1] = "dim_0";
  (*dimension.mutable_event_codes())[2] = "dim_1";

  uint32_t event_code = 8;
  uint64_t index = 8u;
  auto status_or_index = EventCodeToIndexForDimension(event_code, dimension);
  ASSERT_TRUE(status_or_index.ok());
  EXPECT_EQ(status_or_index.ValueOrDie(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.ValueOrDie(), event_code);
}

// Test that EventCodeToIndexForDimension() returns an error status when the
// metric dimension has a max_event_code and the supplied event code is too
// large.
TEST(EventCodeToIndexForDimensionTest, EventCodeLargerThanMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  dimension.set_max_event_code(10);
  (*dimension.mutable_event_codes())[1] = "dim_0";
  (*dimension.mutable_event_codes())[2] = "dim_1";

  uint32_t event_code = 20;
  auto status_or_encoded = EventCodeToIndexForDimension(event_code, dimension);
  ASSERT_FALSE(status_or_encoded.ok());
}

// Test that EventCodeToIndexForDimension() returns an error status when the
// metric dimension has no max_event_code and the supplied event code is not one
// of the valid enumerated event codes.
TEST(EventCodeToIndexForDimensionTest, InvalidEventCodeNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[1] = "dim_0";
  (*dimension.mutable_event_codes())[3] = "dim_1";

  uint32_t event_code = 2;
  auto status_or_index = EventCodeToIndexForDimension(event_code, dimension);
  ASSERT_FALSE(status_or_index.ok());
}

// Test that EventCodeFromIndexForDimension() returns an error status when the
// metric dimension has no max_event_code and the supplied index is larger than
// the number of enumerated event codes.
TEST(EventCodeFromIndexForDimensionTest, InvalidIndexNoMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  (*dimension.mutable_event_codes())[1] = "dim_0";
  (*dimension.mutable_event_codes())[3] = "dim_1";

  uint64_t index = 10;
  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_FALSE(status_or_event_code.ok());
}

// Test that EventCodeFromIndexForDimension() returns an error status when the
// supplied index is larger than the metric definition's max_event_code.
TEST(EventCodeFromIndexForDimensionTest, InvalidIndexMaxEventCode) {
  MetricDefinition::MetricDimension dimension;
  dimension.set_dimension("dimension 1");
  dimension.set_max_event_code(10);

  uint64_t index = 20;
  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_FALSE(status_or_event_code.ok());
}

// Test EventVectorToIndex() when the supplied event vector is valid for the
// metric definition. Also check that EventVectorFromIndex() gives back the
// original event vector.
TEST(EventVectorToIndexTest, WorksWithValidEventCodes) {
  MetricDefinition metric_def;
  // A dimension with no max_event_code and consecutive enumerated event codes.
  auto dim_0 = metric_def.add_metric_dimensions();
  dim_0->set_dimension("dimension_consecutive");
  (*dim_0->mutable_event_codes())[0] = "code_0";
  (*dim_0->mutable_event_codes())[1] = "code_1";
  (*dim_0->mutable_event_codes())[2] = "code_2";

  // A dimension with no max_event_code and consecutive enumerated event codes.
  auto dim_1 = metric_def.add_metric_dimensions();
  dim_1->set_dimension("dimension_non_consecutive");
  (*dim_1->mutable_event_codes())[0] = "code_0";
  (*dim_1->mutable_event_codes())[100] = "code_1";
  (*dim_1->mutable_event_codes())[200] = "code_2";
  (*dim_1->mutable_event_codes())[300] = "code_3";
  // The enumerated event codes from this dimension.
  std::vector<uint32_t> non_consecutive_codes = {0, 100, 200, 300};

  // A dimension with a max_event_code.
  auto dim_2 = metric_def.add_metric_dimensions();
  dim_2->set_dimension("dimension_max_event_code");
  dim_2->set_max_event_code(10);
  (*dim_2->mutable_event_codes())[1] = "code_0";
  (*dim_2->mutable_event_codes())[2] = "code_1";

  // Iterate over all valid event vectors for |metric_def|, testing
  // EventVectorToIndex() and EventVectorFromIndex().
  std::vector<uint32_t> event_vector = {0, 0, 0};
  uint64_t expected = 0;
  for (event_vector[2] = 0; event_vector[2] < uint32_t(dim_2->event_codes_size());
       ++event_vector[2]) {
    for (uint32_t event_code_1 : non_consecutive_codes) {
      event_vector[1] = event_code_1;
      for (event_vector[0] = 0; event_vector[0] < uint32_t(dim_0->event_codes_size());
           event_vector[0]++) {
        auto status_or_index_event_vector = EventVectorToIndex(event_vector, metric_def);
        ASSERT_TRUE(status_or_index_event_vector.ok());

        uint64_t index = status_or_index_event_vector.ValueOrDie();
        EXPECT_EQ(index, expected) << EventVectorAsString(event_vector);

        auto status_or_event_code_event_vector =
            EventVectorFromIndex(index, metric_def.metric_dimensions());
        ASSERT_TRUE(status_or_event_code_event_vector.ok());
        EXPECT_EQ(status_or_event_code_event_vector.ValueOrDie(), event_vector);
        expected++;
      }
    }
  }
}

// Check that EventVectorToIndex() returns an error status when the size of the
// supplied event vector is not equal to the number of metric dimensions.
TEST(EventVectorToIndexTest, WrongEventVectorSize) {
  MetricDefinition metric_def;
  auto dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[1] = "dim_1";
  (*dimension->mutable_event_codes())[2] = "dim_2";

  dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_non_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[100] = "dim_1";
  (*dimension->mutable_event_codes())[200] = "dim_2";
  (*dimension->mutable_event_codes())[300] = "dim_3";

  dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_max_event_code");
  dimension->set_max_event_code(10);
  (*dimension->mutable_event_codes())[1] = "dim_0";
  (*dimension->mutable_event_codes())[2] = "dim_1";

  std::vector<uint32_t> event_vector = {2, 3};
  EXPECT_FALSE(EventVectorToIndex(event_vector, metric_def).ok());
}

// Check that EventVectorFromIndex() returns an error status when the supplied
// index is larger than the number of valid event vectors for the metric
// definition.
TEST(EventVectorFromIndexTest, InvalidEventVectorIndex) {
  MetricDefinition metric_def;
  auto dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[1] = "dim_1";
  (*dimension->mutable_event_codes())[2] = "dim_2";

  dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_non_consecutive");
  (*dimension->mutable_event_codes())[0] = "dim_0";
  (*dimension->mutable_event_codes())[100] = "dim_1";
  (*dimension->mutable_event_codes())[200] = "dim_2";
  (*dimension->mutable_event_codes())[300] = "dim_3";

  dimension = metric_def.add_metric_dimensions();
  dimension->set_dimension("dimension_max_event_code");
  dimension->set_max_event_code(10);
  (*dimension->mutable_event_codes())[1] = "dim_0";
  (*dimension->mutable_event_codes())[2] = "dim_1";

  // There are 132 distinct event vectors. So, 134 cannot refer to an event
  // vector.
  uint64_t invalid_index = 134;
  EXPECT_FALSE(EventVectorFromIndex(invalid_index, metric_def.metric_dimensions()).ok());
}

}  // namespace cobalt::logger
