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

  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.LoggerCalled(LoggerCallsMadeMigratedMetricDimensionLoggerMethod::LogMemoryUsage,
                         GetTestProject());
  }

  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);
  ASSERT_EQ(logger.last_event_logged().occurrence_event().event_code(0), 5);
}

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

  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.PauseLogging();
    for (int i = 0; i < kMany; i++) {
      metrics.LoggerCalled(LoggerCallsMadeMigratedMetricDimensionLoggerMethod::LogMemoryUsage,
                           GetTestProject());
    }
    metrics.ResumeLogging();
  }

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

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

  ASSERT_EQ(logger.call_count(), 0);
  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.BytesUploaded(BytesUploadedMetricDimensionStatus::Attempted, kNumBytes);
  }

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

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

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

  ASSERT_EQ(logger.call_count(), 0);
  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.BytesUploaded(
        PerProjectBytesUploadedMigratedMetricDimensionStatus::Attempted, kNumBytes,
        lib::ProjectIdentifier(lib::CustomerIdentifier(kTestCustomerId), kTestProjectId));
  }

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

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

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

  ASSERT_EQ(logger.call_count(), 0);
  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.BytesStored(
        PerProjectBytesStoredMigratedMetricDimensionStatus::Attempted, kNumBytes,
        lib::ProjectIdentifier(lib::CustomerIdentifier(kTestCustomerId), kTestProjectId));
  }

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

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

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

  ASSERT_EQ(logger.call_count(), 0);
  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.SetSoftwareDistributionInfoCalled(
        {SetSoftwareDistributionInfoCalledMigratedMetricDimensionNewRealm::Valid});
  }

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

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

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

  {
    InternalMetrics::InternalMetricsFlusher flusher = metrics.Flusher();
    metrics.TrackDiskUsage(InternalMetrics::StorageClass::ObservationStore, 90, 100);
  }

  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
