// 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;

  MetricDefinition::MetricDimension *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.value(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.value(), 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.value(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.value(), 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.value(), index);

  auto status_or_event_code = EventCodeFromIndexForDimension(index, dimension);
  ASSERT_TRUE(status_or_event_code.ok());
  EXPECT_EQ(status_or_event_code.value(), 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.
  MetricDefinition::MetricDimension *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.
  MetricDefinition::MetricDimension *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.
  MetricDefinition::MetricDimension *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] < static_cast<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] < static_cast<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.value();
        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.value(), 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;
  MetricDefinition::MetricDimension *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;
  MetricDefinition::MetricDimension *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
