// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_metric/metric.h"

#include "gtest/gtest.h"
#include "pw_log/log.h"

namespace pw::metric {

TEST(Metric, FloatFromObject) {
  // Note leading bit is 1; it is stripped from the name to store the type.
  Token token = 0xf1223344;

  TypedMetric<float> m(token, 1.5f);
  EXPECT_EQ(m.name(), 0x71223344u);
  EXPECT_TRUE(m.is_float());
  EXPECT_FALSE(m.is_int());
  EXPECT_EQ(m.value(), 1.5f);

  m.Set(55.1f);
  EXPECT_EQ(m.value(), 55.1f);

  // No increment operation for float.
}

TEST(Metric, IntFromObject) {
  // Note leading bit is 1; it is stripped from the name to store the type.
  Token token = 0xf1223344;

  TypedMetric<uint32_t> m(token, static_cast<uint32_t>(31337u));
  EXPECT_EQ(m.name(), 0x71223344u);
  EXPECT_TRUE(m.is_int());
  EXPECT_FALSE(m.is_float());
  EXPECT_EQ(m.value(), 31337u);

  m.Set(414u);
  EXPECT_EQ(m.value(), 414u);

  m.Increment();
  EXPECT_EQ(m.value(), 415u);

  m.Increment(11u);
  EXPECT_EQ(m.value(), 426u);
}

TEST(m, IntFromMacroLocal) {
  PW_METRIC(m, "some_metric", 14u);
  EXPECT_TRUE(m.is_int());
  EXPECT_EQ(m.value(), 14u);
}

TEST(Metric, FloatFromMacroLocal) {
  PW_METRIC(m, "some_metric", 3.14f);
  EXPECT_TRUE(m.is_float());
  EXPECT_EQ(m.value(), 3.14f);
}

TEST(Metric, GroupMacroInFunctionContext) {
  PW_METRIC_GROUP(group, "fancy_subsystem");
  PW_METRIC(group, x, "x", 5555u);
  PW_METRIC(group, y, "y", 6.0f);

  // These calls are needed to satisfy GCC, otherwise GCC warns about an unused
  // variable (even though it is used and passed to the group, which adds it):
  //
  //   metric_test.cc:72:20: error: variable 'x' set but not used
  //   [-Werror=unused-but-set-variable]
  //
  x.Increment(10);
  y.Set(5.0f);

  int num_metrics = 0;
  for (auto& m : group.metrics()) {
    PW_UNUSED(m);
    num_metrics++;
  }
  group.Dump();
  EXPECT_EQ(num_metrics, 2);
}

// The below are compile tests to ensure the macros work at global scope.

// Case 1: No group specified.
PW_METRIC(global_x, "global_x", 5555u);
PW_METRIC(global_y, "global_y", 6.0f);

// Case 2: Group specified.
PW_METRIC_GROUP(global_group, "a_global_group");
PW_METRIC(global_group, global_z, "global_x", 5555u);
PW_METRIC(global_group, global_w, "global_y", 6.0f);

// A fake object to illustrate the API and show nesting metrics.
// This also tests creating metrics as members inside a class.
class I2cBus {
 public:
  void Transaction() {
    // An entirely unconvincing fake I2C transaction implementation.
    transactions_.Increment();
    bytes_sent_.Increment(5);
  }

  Group& stats() { return metrics_; }

 private:
  // Test a group with metrics in it, as a class member.
  // Note that in many cases, the group would be passed in externally instead.
  PW_METRIC_GROUP(metrics_, "i2c");
  PW_METRIC(metrics_, bus_errors_, "bus_errors", 0u);
  PW_METRIC(metrics_, transactions_, "transactions", 0u);
  PW_METRIC(metrics_, bytes_sent_, "bytes_sent", 0u);

  // Test metrics without a group, as a class member.
  PW_METRIC(a, "a", 0u);
  PW_METRIC(b, "b", 10.0f);
  PW_METRIC(c, "c", 525u);
};

class Gyro {
 public:
  Gyro(I2cBus& i2c_bus, Group& parent_metrics) : i2c_bus_(i2c_bus) {
    // Make the gyro a child of the I2C bus. Note that the other arrangement,
    // where the i2c bus is a child of the gyro, doesn't work if there are
    // multiple objects on the I2C bus due to the intrusive list mechanism.
    parent_metrics.Add(metrics_);
  }

  void Init() {
    i2c_bus_.Transaction();
    initialized_.Increment();
  }

  void ReadAngularVelocity() {
    // Pretend to be doing some transactions and pulling angular velocity.
    // Pretend this gyro is inefficient and requires multiple transactions.
    i2c_bus_.Transaction();
    i2c_bus_.Transaction();
    i2c_bus_.Transaction();
    num_samples_.Increment();
  }

  Group& stats() { return metrics_; }

 private:
  I2cBus& i2c_bus_;

  // In this case, "gyro" groups the relevant metrics, but it is possible to
  // have freestanding metrics directly without a group; however, those
  // free-standing metrics must be added to a group or list supplied elsewhere
  // for collection.
  PW_METRIC_GROUP(metrics_, "gyro");
  PW_METRIC(metrics_, num_samples_, "num_samples", 1u);
  PW_METRIC(metrics_, init_time_us_, "init_time_us", 1.0f);
  PW_METRIC(metrics_, initialized_, "initialized", 0u);
};

// The below test produces output like:
//
//   "$6doqFw==": {
//     "$05OCZw==": {
//       "$VpPfzg==": 1,
//       "$LGPMBQ==": 1.000000,
//       "$+iJvUg==": 5,
//     }
//     "$9hPNxw==": 65,
//     "$oK7HmA==": 13,
//     "$FCM4qQ==": 0,
//   }
//
// Note the metric names are tokenized with base64. Decoding requires using the
// Pigweed detokenizer. With a detokenizing-enabled logger, you would get:
//
//   "i2c": {
//     "gyro": {
//       "num_sampleses": 1,
//       "init_time_us": 1.000000,
//       "initialized": 5,
//     }
//     "bus_errors": 65,
//     "transactions": 13,
//     "bytes_sent": 0,
//   }
//
TEST(Metric, InlineConstructionWithGroups) {
  I2cBus i2c_bus;
  Gyro gyro(i2c_bus, i2c_bus.stats());

  gyro.Init();
  gyro.ReadAngularVelocity();
  gyro.ReadAngularVelocity();
  gyro.ReadAngularVelocity();
  gyro.ReadAngularVelocity();

  // This "test" doesn't really test anything, and more illustrates how to the
  // metrics could be instantiated in an object tree.
  //
  // Unfortunatlely, testing dump is difficult since we don't have log
  // redirection for tests.
  i2c_bus.stats().Dump();
}

// PW_METRIC_STATIC doesn't support class scopes, since a definition must be
// provided outside of the class body.
// TODO(paulmathieu): add support for class scopes and enable this test
#if 0
class MetricTest: public ::testing::Test {
  public:
    void Increment() {
      metric_.Increment();
    }

  private:
    PW_METRIC_STATIC(metric_, "metric", 0u);
};

TEST_F(MetricTest, StaticWithinAClass) {
  Increment();
}
#endif

Metric* StaticMetricIncrement() {
  PW_METRIC_STATIC(metric, "metric", 0u);
  metric.Increment();
  return &metric;
}

TEST(Metric, StaticWithinAFunction) {
  Metric* metric = StaticMetricIncrement();
  EXPECT_EQ(metric->as_int(), 1u);
  StaticMetricIncrement();
  EXPECT_EQ(metric->as_int(), 2u);
}

}  // namespace pw::metric
