// Copyright 2019 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/internal_metrics.h"

#include <vector>

#include <gtest/gtest.h>

#include "src/logger/fake_logger.h"

namespace cobalt::logger {

constexpr int64_t kNumBytes = 123;
constexpr uint32_t kTestCustomerId = 1;
constexpr uint32_t kTestProjectId = 2;
constexpr uint32_t kMany = 100;

class InternalMetricsImplTest : public ::testing::Test {
 public:
  static Project GetTestProject() {
    Project project;
    project.set_customer_id(kTestCustomerId);
    project.set_customer_name("test");
    project.set_project_id(kTestProjectId);
    project.set_project_name("project");
    return project;
  }
};

TEST_F(InternalMetricsImplTest, LoggerCalled) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.LoggerCalled(PerProjectLoggerCallsMadeMetricDimensionLoggerMethod::LogMemoryUsage,
                       GetTestProject());

  ASSERT_EQ(logger.call_count(), 2);
  ASSERT_TRUE(logger.last_event_logged().has_event_count_event());
  ASSERT_EQ(logger.last_event_logged().event_count_event().component(), "test/project");
}

TEST_F(InternalMetricsImplTest, LoggerCalledPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.LoggerCalled(PerProjectLoggerCallsMadeMetricDimensionLoggerMethod::LogMemoryUsage,
                         GetTestProject());
  }
  metrics.ResumeLogging();

  ASSERT_EQ(logger.call_count(), 0);
}

TEST_F(InternalMetricsImplTest, BytesUploaded) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  ASSERT_EQ(logger.call_count(), 0);
  metrics.BytesUploaded(PerDeviceBytesUploadedMetricDimensionStatus::Attempted, kNumBytes);

  ASSERT_EQ(logger.call_count(), 2);
  ASSERT_TRUE(logger.last_event_logged().has_occurrence_event());
  ASSERT_EQ(logger.last_event_logged().metric_id(), kBytesUploadedMetricId);
  ASSERT_EQ(logger.last_event_logged().occurrence_event().count(), kNumBytes);
}

TEST_F(InternalMetricsImplTest, BytesUploadedPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.BytesUploaded(PerDeviceBytesUploadedMetricDimensionStatus::Attempted, kNumBytes);
  }
  metrics.ResumeLogging();
  ASSERT_EQ(logger.call_count(), 0);
}

TEST_F(InternalMetricsImplTest, MegaBytesUploaded) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  ASSERT_EQ(logger.call_count(), 0);
  metrics.BytesUploaded(PerProjectBytesUploadedMetricDimensionStatus::Attempted, kNumBytes,
                        kTestCustomerId, kTestProjectId);

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_event_count_event());
  ASSERT_EQ(logger.last_event_logged().event_count_event().count(), kNumBytes);
}

TEST_F(InternalMetricsImplTest, MegaBytesUploadedPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.BytesUploaded(PerProjectBytesUploadedMetricDimensionStatus::Attempted, kNumBytes,
                          kTestCustomerId, kTestProjectId);
  }
  metrics.ResumeLogging();
  ASSERT_EQ(logger.call_count(), 0);
}

TEST_F(InternalMetricsImplTest, BytesStored) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  ASSERT_EQ(logger.call_count(), 0);
  metrics.BytesStored(PerProjectBytesStoredMetricDimensionStatus::Attempted, kNumBytes,
                      kTestCustomerId, kTestProjectId);

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_memory_usage_event());
  ASSERT_EQ(logger.last_event_logged().memory_usage_event().bytes(), kNumBytes);
}

TEST_F(InternalMetricsImplTest, BytesStoredPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.BytesStored(PerProjectBytesStoredMetricDimensionStatus::Attempted, kNumBytes,
                        kTestCustomerId, kTestProjectId);
  }
  metrics.ResumeLogging();
  ASSERT_EQ(logger.call_count(), 0);
}

TEST_F(InternalMetricsImplTest, IdleObservationUploadWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  ASSERT_EQ(logger.call_count(), 0);
  metrics.IdleObservationUpload(IdleObservationUploadMetricDimensionDeviceState_Active);

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_event_count_event());
  ASSERT_EQ(logger.last_event_logged().event_count_event().count(), 1);
}

TEST_F(InternalMetricsImplTest, IdleObservationUploadPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.IdleObservationUpload(IdleObservationUploadMetricDimensionDeviceState_Active);
  }
  metrics.ResumeLogging();
  ASSERT_EQ(logger.call_count(), 0);
}

TEST_F(InternalMetricsImplTest, SetSoftwareDistributionInfoCalledWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  ASSERT_EQ(logger.call_count(), 0);
  metrics.SetSoftwareDistributionInfoCalled(
      {SetSoftwareDistributionInfoCalledMetricDimensionNewRealm::Valid});

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_event_count_event());
  ASSERT_EQ(logger.last_event_logged().event_count_event().count(), 1);
}

TEST_F(InternalMetricsImplTest, SetSoftwareDistributionInfoCalledPauseWorks) {
  testing::FakeLogger logger;
  InternalMetricsImpl metrics(&logger);

  metrics.PauseLogging();
  for (int i = 0; i < kMany; i++) {
    metrics.SetSoftwareDistributionInfoCalled(
        {SetSoftwareDistributionInfoCalledMetricDimensionNewRealm::Valid});
  }
  metrics.ResumeLogging();
  ASSERT_EQ(logger.call_count(), 0);
}

}  // namespace cobalt::logger
