// 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"
#include "src/public/lib/registry_identifiers.h"

namespace cobalt::logger {

constexpr size_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, nullptr);

  metrics.LoggerCalled(PerProjectLoggerCallsMadeMigratedMetricDimensionLoggerMethod::LogMemoryUsage,
                       GetTestProject());
  metrics.Flush();

  ASSERT_EQ(logger.call_count(), 2);
  ASSERT_TRUE(logger.last_event_logged().has_occurrence_event());
  ASSERT_EQ(logger.last_event_logged().occurrence_event().count(), 1);
  ASSERT_EQ(logger.last_event_logged().occurrence_event().event_code(0), 10);
}

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

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

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

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

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

  ASSERT_EQ(logger.call_count(), 1);
  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 inner_metrics(&logger, nullptr);
  InternalMetricsPauseWrapper metrics(&inner_metrics);

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

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

  ASSERT_EQ(logger.call_count(), 0);
  metrics.BytesUploaded(
      PerProjectBytesUploadedMigratedMetricDimensionStatus::Attempted, kNumBytes,
      lib::ProjectIdentifier(lib::CustomerIdentifier(kTestCustomerId), kTestProjectId));
  metrics.Flush();

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_integer_event());
  ASSERT_EQ(logger.last_event_logged().integer_event().value(), kNumBytes);
}

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

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

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

  ASSERT_EQ(logger.call_count(), 0);
  metrics.BytesStored(
      PerProjectBytesStoredMigratedMetricDimensionStatus::Attempted, kNumBytes,
      lib::ProjectIdentifier(lib::CustomerIdentifier(kTestCustomerId), kTestProjectId));
  metrics.Flush();

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_integer_event());
  ASSERT_EQ(logger.last_event_logged().integer_event().value(), kNumBytes);
}

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

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

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

  ASSERT_EQ(logger.call_count(), 0);
  metrics.IdleObservationUpload(IdleObservationUploadMigratedMetricDimensionDeviceState_Active);
  metrics.Flush();

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_occurrence_event());
  ASSERT_EQ(logger.last_event_logged().occurrence_event().count(), 1);
}

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

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

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

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

  ASSERT_EQ(logger.call_count(), 1);
  ASSERT_TRUE(logger.last_event_logged().has_occurrence_event());
  ASSERT_EQ(logger.last_event_logged().occurrence_event().count(), 1);
}

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

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

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

  metrics.TrackDiskUsage(InternalMetrics::StorageClass::ObservationStore, 90, 100);
  metrics.Flush();

  ASSERT_EQ(logger.call_count(), 2);
  ASSERT_TRUE(logger.nth_event_logged(0).has_integer_event());
  ASSERT_EQ(logger.nth_event_logged(0).integer_event().value(), 90);
  ASSERT_TRUE(logger.nth_event_logged(1).has_integer_event());
  ASSERT_EQ(logger.nth_event_logged(1).integer_event().value(), 900);
}

}  // namespace cobalt::logger
