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