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

  group.Dump();
  EXPECT_EQ(group.metrics().size(), 2u);
}

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