// Copyright 2018 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 <memory>
#include <string>
#include <utility>

#include "src/logger/internal_metrics_config.cb.h"
#include "src/logging.h"

namespace cobalt::logger {

std::unique_ptr<InternalMetrics> InternalMetrics::NewWithLogger(LoggerInterface* logger) {
  if (logger) {
    return std::make_unique<InternalMetricsImpl>(logger);
  }
  return std::make_unique<NoOpInternalMetrics>();
}

InternalMetricsImpl::InternalMetricsImpl(LoggerInterface* logger)
    : paused_(false), logger_(logger) {
  CHECK(logger_);
}

void InternalMetricsImpl::LoggerCalled(PerProjectLoggerCallsMadeMetricDimensionLoggerMethod method,
                                       const Project& project) {
  if (paused_) {
    return;
  }

  auto status = logger_->LogEventCount(kLoggerCallsMadeMetricId, method, "", 0, 1);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::LoggerCalled: LogEventCount() returned status=" << status;
  }

  std::ostringstream component;
  component << project.customer_name() << '/' << project.project_name();
  status =
      logger_->LogEventCount(kPerProjectLoggerCallsMadeMetricId, method, component.str(), 0, 1);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::LoggerCalled: LogEventCount() returned status=" << status;
  }
}

void InternalMetricsImpl::BytesUploaded(PerDeviceBytesUploadedMetricDimensionStatus upload_status,
                                        int64_t byte_count) {
  if (paused_) {
    return;
  }

  Status status =
      logger_->LogEventCount(kPerDeviceBytesUploadedMetricId, upload_status, "", 0, byte_count);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::BytesUploaded: LogEventCount() returned "
            << "status=" << status;
  }

  status = logger_->LogOccurrence(kBytesUploadedMetricId, byte_count, {upload_status});

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::BytesUploaded: LogOccurrence() returned "
            << "status=" << status;
  }
}

void InternalMetricsImpl::BytesUploaded(PerProjectBytesUploadedMetricDimensionStatus upload_status,
                                        int64_t byte_count, uint32_t customer_id,
                                        uint32_t project_id) {
  if (paused_) {
    return;
  }

  std::ostringstream component;
  component << customer_id << '/' << project_id;

  auto status = logger_->LogEventCount(kPerProjectBytesUploadedMetricId, upload_status,
                                       component.str(), 0, byte_count);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::BytesUploaded: LogEventCount() returned "
            << "status=" << status;
  }
}

void InternalMetricsImpl::BytesStored(PerProjectBytesStoredMetricDimensionStatus upload_status,
                                      int64_t byte_count, uint32_t customer_id,
                                      uint32_t project_id) {
  if (paused_) {
    return;
  }

  std::ostringstream component;
  component << customer_id << '/' << project_id;

  auto status = logger_->LogMemoryUsage(kPerProjectBytesStoredMetricId, upload_status,
                                        component.str(), byte_count);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::BytesStored: LogMemoryUsage() returned status=" << status;
  }
}

void InternalMetricsImpl::IdleObservationUpload(
    IdleObservationUploadMetricDimensionDeviceState state) {
  if (paused_) {
    return;
  }

  auto status = logger_->LogEventCount(kIdleObservationUploadMetricId, state, "", 0, 1);
  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::IdleObservationUpload: LogEventCount() returned status="
            << status;
  }
}

void InternalMetricsImpl::InaccurateClockEventsCached(int64_t event_count, uint32_t customer_id,
                                                      uint32_t project_id) {
  if (paused_) {
    return;
  }

  std::ostringstream component;
  component << customer_id << '/' << project_id;

  auto status = logger_->LogEventCount(kInaccurateClockEventsCachedMetricId, {}, component.str(), 0,
                                       event_count);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::InaccurateClockEventsCached: LogEventCount() returned status="
            << status;
  }
}

void InternalMetricsImpl::InaccurateClockEventsDropped(int64_t event_count, uint32_t customer_id,
                                                       uint32_t project_id) {
  if (paused_) {
    return;
  }

  std::ostringstream component;
  component << customer_id << '/' << project_id;

  auto status = logger_->LogEventCount(kInaccurateClockEventsDroppedMetricId, {}, component.str(),
                                       0, event_count);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::InaccurateClockEventsDropped: LogEventCount() returned status="
            << status;
  }
}

void InternalMetricsImpl::SetSoftwareDistributionInfoCalled(
    SetSoftwareDistributionInfoCalledEventCodes event_codes) {
  if (paused_) {
    return;
  }

  auto status = logger_->LogEventCount(kSetSoftwareDistributionInfoCalledMetricId,
                                       event_codes.ToVector(), "", 0, 1);

  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::SetSoftwareDistributionInfoCalled: LogEventCount() returned "
               "status="
            << status;
  }
}

const float kPerMilleMultiplier = 1000.0;
void InternalMetricsImpl::TrackDiskUsage(StorageClass storage_class, int64_t bytes,
                                         int64_t max_bytes) {
  if (paused_) {
    return;
  }

  // N.B. This method may only include Cobalt 1.1 metrics. Using Cobalt 1.0 metrics here have the
  // potential to cause logging loops.
  auto status = logger_->LogInteger(kStoreUsageMetricId, bytes, {storage_class});
  if (status != kOK) {
    VLOG(1) << "InternalMetricsImpl::TrackDiskUsage: LogInteger(disk_usage) returned status="
            << status;
  }

  if (max_bytes >= 0) {
    auto fullness_per_mille = static_cast<uint32_t>(
        (static_cast<float>(bytes) / static_cast<float>(max_bytes)) * kPerMilleMultiplier);
    status = logger_->LogInteger(kStoreFullnessMetricId, fullness_per_mille, {storage_class});
    if (status != kOK) {
      VLOG(1) << "InternalMetricsImpl::TrackDiskUsage: LogInteger(disk_fullness) returned status="
              << status;
    }
  }
}

}  // namespace cobalt::logger
