// 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/event_loggers.h"

#include <memory>
#include <string>

#include <google/protobuf/repeated_field.h>

#include "src/algorithms/rappor/rappor_config_helper.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/status.h"
#include "src/logger/event_record.h"
#include "src/logging.h"
#include "src/pb/event.pb.h"
#include "src/pb/observation.pb.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/report_definition.pb.h"
#include "src/tracing.h"

namespace cobalt::logger::internal {

using ::cobalt::local_aggregation::EventAggregator;
using ::cobalt::rappor::RapporConfigHelper;
using ::cobalt::util::TimeToDayIndex;
using ::cobalt::util::TimeToHourId;
using ::google::protobuf::RepeatedField;
using ::google::protobuf::RepeatedPtrField;

constexpr char TRACE_PREFIX[] = "[COBALT_EVENT_TRACE] ";

namespace {

Status FromStatus(const cobalt::util::Status& status) {
  switch (status.error_code()) {
    case cobalt::util::StatusCode::OK:
      return kOK;
    case cobalt::util::StatusCode::INVALID_ARGUMENT:
      return kInvalidArguments;
    default:
      return kOther;
  }
}

}  // namespace

std::unique_ptr<EventLogger> EventLogger::Create(
    MetricDefinition::MetricType metric_type, const Encoder* encoder,
    EventAggregator* event_aggregator, local_aggregation::LocalAggregation* local_aggregation,
    const ObservationWriter* observation_writer,
    const system_data::SystemDataInterface* system_data) {
  switch (metric_type) {
    case MetricDefinition::EVENT_OCCURRED: {
      return std::make_unique<internal::EventOccurredEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::EVENT_COUNT: {
      return std::make_unique<internal::EventCountEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::ELAPSED_TIME: {
      return std::make_unique<internal::ElapsedTimeEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::FRAME_RATE: {
      return std::make_unique<internal::FrameRateEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::MEMORY_USAGE: {
      return std::make_unique<internal::MemoryUsageEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::INT_HISTOGRAM: {
      return std::make_unique<internal::IntHistogramEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::OCCURRENCE: {
      return std::make_unique<internal::OccurrenceEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::INTEGER: {
      return std::make_unique<internal::IntegerEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::INTEGER_HISTOGRAM: {
      return std::make_unique<internal::IntegerHistogramEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::STRING: {
      return std::make_unique<internal::StringEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    case MetricDefinition::CUSTOM: {
      return std::make_unique<internal::CustomEventLogger>(
          encoder, event_aggregator, local_aggregation, observation_writer, system_data);
    }
    default: {
      LOG(ERROR) << "Failed to process a metric type of " << metric_type;
      return nullptr;
    }
  }
}

std::string EventLogger::TraceEvent(const EventRecord& event_record) {
  if (!event_record.metric()->meta_data().also_log_locally()) {
    return "";
  }

  auto event = event_record.event();

  std::stringstream ss;
  ss << "Day index: " << event->day_index() << std::endl;
  if (event->has_event_occurred_event()) {
    const auto& e = event->event_occurred_event();
    ss << "EventOccurredEvent: " << e.event_code() << std::endl;
  } else if (event->has_event_count_event()) {
    const auto& e = event->event_count_event();
    ss << "EventCountEvent:" << std::endl;
    ss << "EventCodes:";
    for (const auto& code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Component: " << e.component()
       << ", PeriodDurationMicros: " << e.period_duration_micros() << ", Count: " << e.count()
       << std::endl;
  } else if (event->has_elapsed_time_event()) {
    const auto& e = event->elapsed_time_event();
    ss << "ElapsedTimeEvent:" << std::endl;
    ss << "EventCodes:";
    for (const auto& code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Component: " << e.component() << ", ElapsedMicros: " << e.elapsed_micros()
       << std::endl;
  } else if (event->has_frame_rate_event()) {
    const auto& e = event->frame_rate_event();
    ss << "FrameRateEvent:" << std::endl;
    ss << "EventCodes:";
    for (const auto& code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Component: " << e.component()
       << ", FramesPer1000Seconds: " << e.frames_per_1000_seconds() << std::endl;
  } else if (event->has_memory_usage_event()) {
    const auto& e = event->memory_usage_event();
    ss << "MemoryUsageEvent:" << std::endl;
    ss << "EventCodes:";
    for (const auto& code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Component: " << e.component() << ", Bytes: " << e.bytes() << std::endl;
  } else if (event->has_int_histogram_event()) {
    const auto& e = event->int_histogram_event();
    ss << "IntHistogramEvent:" << std::endl;
    ss << "EventCodes:";
    for (const auto& code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Component: " << e.component() << std::endl;
    for (const auto& bucket : e.buckets()) {
      ss << "| " << bucket.index() << " = " << bucket.count() << std::endl;
    }
  } else if (event->has_occurrence_event()) {
    const OccurrenceEvent& e = event->occurrence_event();
    ss << "OccurrenceEvent:" << std::endl;
    ss << "EventCodes:";
    for (uint32_t code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Count: " << e.count() << std::endl;
  } else if (event->has_integer_event()) {
    const IntegerEvent& e = event->integer_event();
    ss << "IntegerEvent:" << std::endl;
    ss << "EventCodes:";
    for (uint32_t code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", Value: " << e.value() << std::endl;
  } else if (event->has_integer_histogram_event()) {
    const IntegerHistogramEvent& e = event->integer_histogram_event();
    ss << "IntegerHistogramEvent:" << std::endl;
    ss << "EventCodes:";
    for (uint32_t code : e.event_code()) {
      ss << " " << code;
    }
    for (const HistogramBucket& bucket : e.buckets()) {
      ss << "| " << bucket.index() << " = " << bucket.count() << std::endl;
    }
  } else if (event->has_string_event()) {
    const StringEvent& e = event->string_event();
    ss << "StringEvent:" << std::endl;
    ss << "EventCodes:";
    for (uint32_t code : e.event_code()) {
      ss << " " << code;
    }
    ss << ", String: " << e.string_value() << std::endl;
  } else if (event->has_custom_event()) {
    const auto& e = event->custom_event();
    ss << "CustomEvent:";
    if (e.values().empty()) {
      ss << " (Empty)";
    }
    ss << std::endl;
    for (const auto& entry : e.values()) {
      switch (entry.second.data_case()) {
        ss << "| " << entry.first << " = ";
        case CustomDimensionValue::kStringValue:
          ss << entry.second.string_value();
          break;
        case CustomDimensionValue::kIntValue:
          ss << entry.second.int_value();
          break;
        case CustomDimensionValue::kBlobValue:
          ss << "Blob";
          break;
        case CustomDimensionValue::kIndexValue:
          ss << entry.second.index_value();
          break;
        case CustomDimensionValue::kDoubleValue:
          ss << entry.second.double_value();
          break;
        default:
          ss << "No dimension value";
          break;
      }
      ss << std::endl;
    }
  }

  return ss.str();
}

void EventLogger::TraceLogFailure(const Status& status, const EventRecord& event_record,
                                  const std::string& trace, const ReportDefinition& report) {
  if (!event_record.metric()->meta_data().also_log_locally()) {
    return;
  }

  LOG(INFO) << TRACE_PREFIX << "("
            << event_record.project_context()->RefMetric(event_record.metric()).FullyQualifiedName()
            << "): Error (" << status << ")" << std::endl
            << trace << "While trying to send report: " << report.report_name() << std::endl;
}

void EventLogger::TraceLogSuccess(const EventRecord& event_record, const std::string& trace) {
  if (!event_record.metric()->meta_data().also_log_locally()) {
    return;
  }

  LOG(INFO) << TRACE_PREFIX << "("
            << event_record.project_context()->RefMetric(event_record.metric()).FullyQualifiedName()
            << "):" << std::endl
            << trace;
}

Status EventLogger::Log(std::unique_ptr<EventRecord> event_record,
                        const std::chrono::system_clock::time_point& event_timestamp) {
  TRACE_DURATION("cobalt_core", "EventLogger::Log", "metric_id", event_record->metric()->id());

  FinalizeEvent(event_record.get(), event_timestamp);

  if (system_data_) {
    if (system_data_->release_stage() > event_record->metric()->meta_data().max_release_stage()) {
      // Quietly ignore this metric.
      LOG_FIRST_N(INFO, 10) << "Not logging metric `"
                            << event_record->project_context()->FullMetricName(
                                   *event_record->metric())
                            << "` because its max_release_stage ("
                            << event_record->metric()->meta_data().max_release_stage()
                            << ") is lower than the device's current release_stage: "
                            << system_data_->release_stage();
      return kOK;
    }
  }

  int num_reports = event_record->metric()->reports_size();
  int report_index = 0;
  if (event_record->metric()->reports_size() == 0) {
    VLOG(1) << "Warning: An event was logged for a metric with no reports "
               "defined: "
            << event_record->project_context()->FullMetricName(*event_record->metric());
  }

  // Store the trace before attempting to log the event. This way, if parts of
  // the event are moved out of the object, the resulting trace will still have
  // useful information.
  auto trace = TraceEvent(*event_record);

  Status status;
  if (IsOnePointOne()) {
    const cobalt::util::Status cobalt_status = local_aggregation()->AddEvent(*event_record);
    status = FromStatus(cobalt_status);
    if (!cobalt_status.ok()) {
      LOG(ERROR) << "Error occurred while locally aggregating event: "
                 << cobalt_status.error_message();
      TraceLogFailure(status, *event_record, trace, event_record->metric()->reports(0));
      return status;
    }
  } else {
    for (const auto& report : event_record->metric()->reports()) {
      status = MaybeUpdateLocalAggregation(report, *event_record);
      if (status != kOK) {
        TraceLogFailure(status, *event_record, trace, report);
        return status;
      }

      // If we are processing the final report, then we set may_invalidate
      // to true in order to allow data to be moved out of |event_record|
      // instead of being copied. One example where this is useful is when
      // creating an immediate Observation of type Histogram. In that case
      // we can move the histogram from the Event to the Observation and
      // avoid copying. Since the |event_record| is invalidated, any other
      // operation on the |event_record| must be performed before this for
      // loop.
      bool may_invalidate = ++report_index == num_reports;
      status = MaybeGenerateImmediateObservation(report, may_invalidate, event_record.get());
      if (status != kOK) {
        TraceLogFailure(status, *event_record, trace, report);
        return status;
      }
    }
  }

  TraceLogSuccess(*event_record, trace);
  return kOK;
}

Status EventLogger::PrepareAndValidateEvent(uint32_t metric_id,
                                            MetricDefinition::MetricType expected_type,
                                            EventRecord* event_record) {
  if (event_record->metric() == nullptr) {
    LOG(ERROR) << "There is no metric with ID '" << metric_id << "' registered "
               << "in project '" << event_record->project_context()->FullyQualifiedName() << "'.";
    return kInvalidArguments;
  }
  if (event_record->metric()->metric_type() != expected_type) {
    LOG(ERROR) << "Metric "
               << event_record->project_context()->FullMetricName(*event_record->metric())
               << " is not of type " << expected_type << " instead it is of type "
               << event_record->metric()->metric_type() << ".";
    return kInvalidArguments;
  }
  return ValidateEvent(*event_record);
}

void EventLogger::FinalizeEvent(EventRecord* event_record,
                                const std::chrono::system_clock::time_point& event_timestamp) {
  // Compute the day_index and hour index.
  auto now = std::chrono::system_clock::to_time_t(event_timestamp);
  event_record->event()->set_day_index(
      TimeToDayIndex(now, event_record->metric()->time_zone_policy()));
  event_record->event()->set_hour_id(TimeToHourId(now, event_record->metric()->time_zone_policy()));
}

Status EventLogger::ValidateEvent(const EventRecord& /*event_record*/) { return kOK; }

Status EventLogger::ValidateEventCodes(const MetricDefinition& metric,
                                       const RepeatedField<uint32_t>& event_codes,
                                       const std::string& full_metric_name) {
  // Special case: Users of the version of the Log*() method that takes
  // a single event code as opposed to a vector of event codes use the
  // convention of passing a zero value for the single event code in the
  // case that the metric does not have any metric dimensions defined. We have
  // no way of distinguishing here that case from the case in which the user
  // invoked the other version of the method and explicitly passed a vector of
  // length one containing a single zero event code. Therefore we must accept
  // a single 0 event code when there are no metric dimensions defined.
  // The packing of multiple event codes into a single integer field in an
  // Observation (see config/packed_event_codes.h) does not distinguish
  // between a single event code with value 0 and an empty list of event codes.
  // Therefore the server also cannot tell the difference between these two
  // cases just by looking at an Observation and relies on the metric definition
  // to distinguish them. Consequently there is no harm in us passing the
  // single zero value to the Encoder: It will produce the same Observation
  // whether or not we do.
  if (metric.metric_dimensions_size() == 0 && event_codes.size() == 1 && event_codes.Get(0) == 0) {
    return kOK;
  }
  // When new dimensions are added to a metric, they can only be appended, not deleted or inserted.
  // Because of this, and because metric definitions may change before the matching code does, we
  // want to accept events where fewer than the expected number of event_codes have been provided.
  if (event_codes.size() > metric.metric_dimensions_size()) {
    LOG(ERROR) << "The number of event_codes given, " << event_codes.size()
               << ", is more than the number of metric_dimensions, "
               << metric.metric_dimensions_size() << ", for metric " << full_metric_name << ".";
    return kInvalidArguments;
  }
  for (int i = 0; i < event_codes.size(); i++) {
    const auto& dim = metric.metric_dimensions(i);
    auto code = event_codes.Get(i);

    // This verifies the two possible validation modes for a metric_dimension.
    //
    // 1. If it has a max_event_code, then all we do is verify that the supplied
    //    code is <= that value
    //
    // 2. If no max_event_code is specified, we verify that the supplied code
    //    maps to one of the values in the event_code map.
    if (dim.max_event_code() > 0) {
      if (code > dim.max_event_code()) {
        LOG(ERROR) << "The event_code given for dimension " << i << ", " << code
                   << ", exceeds the max_event_code for that dimension, " << dim.max_event_code()
                   << ", for metric " << full_metric_name;
        return kInvalidArguments;
      }
    } else {
      bool valid = false;
      for (const auto& event_code : dim.event_codes()) {
        if (event_code.first == code) {
          valid = true;
          break;
        }
      }

      if (!valid) {
        LOG(ERROR) << "The event_code given for dimension " << i << ", " << code
                   << ", is not a valid event code for that dimension."
                   << ". You must either define this event code in"
                      " the metric_dimension, or set max_event_code >= "
                   << code << ", for metric " << full_metric_name;
        return kInvalidArguments;
      }
    }
  }
  return kOK;
}

// The default implementation of MaybeUpdateLocalAggregation does nothing
// and returns OK.
Status EventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& /*report*/,
                                                const EventRecord& /*event_record*/) {
  // In Cobalt 1.1 calling MaybeUpdateLocalAggregation is considered an error.
  if (IsOnePointOne()) {
    return kOther;
  }
  return kOK;
}

Status EventLogger::MaybeGenerateImmediateObservation(const ReportDefinition& report,
                                                      bool may_invalidate,
                                                      EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "EventLogger::MaybeGenerateImmediateObservation");
  // In Cobalt 1.1 calling MaybeGenerateImmediateObservation is considered an error.
  if (IsOnePointOne()) {
    return kOther;
  }

  auto encoder_result = MaybeEncodeImmediateObservation(report, may_invalidate, event_record);
  if (encoder_result.status != kOK) {
    return encoder_result.status;
  }
  if (encoder_result.observation == nullptr) {
    return kOK;
  }
  return observation_writer_->WriteObservation(encoder_result.observation,
                                               std::move(encoder_result.metadata));
}

// The default implementation of MaybeEncodeImmediateObservation does
// nothing and returns OK.
Encoder::Result EventLogger::MaybeEncodeImmediateObservation(const ReportDefinition& /*report*/,
                                                             bool /*may_invalidate*/,
                                                             EventRecord* /*event_record*/) {
  TRACE_DURATION("cobalt_core", "EventLogger::MaybeEncodeImmediateObservation");
  Encoder::Result result;
  result.status = kOK;
  result.observation = nullptr;
  return result;
}

Encoder::Result EventLogger::BadReportType(const std::string& full_metric_name,
                                           const ReportDefinition& report) {
  LOG(ERROR) << "Invalid Cobalt config: Report " << report.report_name() << " for metric "
             << full_metric_name << " is not of an appropriate type for the metric type.";
  Encoder::Result encoder_result;
  encoder_result.status = kInvalidConfig;
  return encoder_result;
}

/////////////// EventOccurredEventLogger method implementations ///////////////////

Status EventOccurredEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.event()->has_event_occurred_event());
  if (event_record.metric()->metric_dimensions_size() != 1) {
    LOG(ERROR) << "The Metric "
               << event_record.project_context()->FullMetricName(*event_record.metric())
               << " has the wrong number of metric_dimensions. A metric of "
                  "type EVENT_OCCURRED must have exactly one metric_dimension.";
    return kInvalidConfig;
  }

  const auto& event_occurred_event = event_record.event()->event_occurred_event();
  if (event_occurred_event.event_code() >
      event_record.metric()->metric_dimensions(0).max_event_code()) {
    LOG(ERROR) << "The event_code " << event_occurred_event.event_code() << " exceeds "
               << event_record.metric()->metric_dimensions(0).max_event_code()
               << ", the max_event_code for Metric "
               << event_record.project_context()->FullMetricName(*event_record.metric()) << ".";
    return kInvalidArguments;
  }
  return kOK;
}

Encoder::Result EventOccurredEventLogger::MaybeEncodeImmediateObservation(
    const ReportDefinition& report, bool /*may_invalidate*/, EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "EventOccurredEventLogger::MaybeEncodeImmediateObservation");
  const MetricDefinition& metric = *(event_record->metric());
  const Event& event = *(event_record->event());
  CHECK(event.has_event_occurred_event());
  const auto& event_occurred_event = event.event_occurred_event();
  switch (report.report_type()) {
    // Each report type has its own logic for generating immediate
    // observations.
    case ReportDefinition::SIMPLE_OCCURRENCE_COUNT: {
      return encoder()->EncodeBasicRapporObservation(
          event_record->project_context()->RefMetric(&metric), &report, event.day_index(),
          event_occurred_event.event_code(), RapporConfigHelper::BasicRapporNumCategories(metric));
    }
      // Report type UNIQUE_N_DAY_ACTIVES is valid but should not result in
      // generation of an immediate observation.
    case ReportDefinition::UNIQUE_N_DAY_ACTIVES: {
      Encoder::Result result;
      result.status = kOK;
      result.observation = nullptr;
      result.metadata = nullptr;
      return result;
    }

    default:
      return BadReportType(event_record->project_context()->FullMetricName(metric), report);
  }
}

Status EventOccurredEventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                                             const EventRecord& event_record) {
  switch (report.report_type()) {
    case ReportDefinition::UNIQUE_N_DAY_ACTIVES: {
      return event_aggregator()->AddUniqueActivesEvent(report.id(), event_record);
    }
    default:
      return kOK;
  }
}

///////////// EventCountEventLogger method implementations //////////////////////////

Status EventCountEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.metric());
  const auto& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->event_count_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

Encoder::Result EventCountEventLogger::MaybeEncodeImmediateObservation(
    const ReportDefinition& report, bool /*may_invalidate*/, EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "EventCountEventLogger::MaybeEncodeImmediateObservation");
  const MetricDefinition& metric = *(event_record->metric());
  const Event& event = *(event_record->event());
  CHECK(event.has_event_count_event());
  auto* event_count_event = event_record->event()->mutable_event_count_event();
  switch (report.report_type()) {
    // Each report type has its own logic for generating immediate observations.
    case ReportDefinition::EVENT_COMPONENT_OCCURRENCE_COUNT:
    case ReportDefinition::INT_RANGE_HISTOGRAM:
    case ReportDefinition::NUMERIC_AGGREGATION: {
      return encoder()->EncodeIntegerEventObservation(
          event_record->project_context()->RefMetric(&metric), &report, event.day_index(),
          event_count_event->event_code(), event_count_event->component(),
          event_count_event->count());
    }
    // Report type PER_DEVICE_NUMERIC_STATS and PER_DEVICE_HISTOGRAM are valid but should not result
    // in generation of an immediate observation.
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      Encoder::Result result;
      result.status = kOK;
      result.observation = nullptr;
      result.metadata = nullptr;
      return result;
    }

    default:
      return BadReportType(event_record->project_context()->FullMetricName(metric), report);
  }
}

Status EventCountEventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                                          const EventRecord& event_record) {
  switch (report.report_type()) {
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      return event_aggregator()->AddEventCountEvent(report.id(), event_record);
    }
    default:
      return kOK;
  }
}

///////////// IntegerPerformanceEventLogger method implementations /////////////

Encoder::Result IntegerPerformanceEventLogger::MaybeEncodeImmediateObservation(
    const ReportDefinition& report, bool /*may_invalidate*/, EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "IntegerPerformanceEventLogger::MaybeEncodeImmediateObservation");
  const MetricDefinition& metric = *(event_record->metric());
  const Event& event = *(event_record->event());
  switch (report.report_type()) {
    // Each report type has its own logic for generating immediate
    // observations.
    case ReportDefinition::NUMERIC_AGGREGATION:
    case ReportDefinition::INT_RANGE_HISTOGRAM: {
      return encoder()->EncodeIntegerEventObservation(
          event_record->project_context()->RefMetric(&metric), &report, event.day_index(),
          EventCodes(event), Component(event), IntValue(event));
      break;
    }
    // Report type PER_DEVICE_NUMERIC_STATS and PER_DEVICE_HISTOGRAM are valid but should not result
    // in generation of an immediate observation.
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      Encoder::Result result;
      result.status = kOK;
      result.observation = nullptr;
      result.metadata = nullptr;
      return result;
    }
    default:
      return BadReportType(event_record->project_context()->FullMetricName(metric), report);
  }
}

////////////// ElapsedTimeEventLogger method implementations ///////////////////

const RepeatedField<uint32_t>& ElapsedTimeEventLogger::EventCodes(const Event& event) {
  CHECK(event.has_elapsed_time_event());
  return event.elapsed_time_event().event_code();
}

std::string ElapsedTimeEventLogger::Component(const Event& event) {
  CHECK(event.has_elapsed_time_event());
  return event.elapsed_time_event().component();
}

int64_t ElapsedTimeEventLogger::IntValue(const Event& event) {
  CHECK(event.has_elapsed_time_event());
  return event.elapsed_time_event().elapsed_micros();
}

Status ElapsedTimeEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.metric());
  const auto& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->elapsed_time_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

Status ElapsedTimeEventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                                           const EventRecord& event_record) {
  switch (report.report_type()) {
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      return event_aggregator()->AddElapsedTimeEvent(report.id(), event_record);
    }
    default:
      return kOK;
  }
}

//////////////// FrameRateEventLogger method implementations ///////////////////

const RepeatedField<uint32_t>& FrameRateEventLogger::EventCodes(const Event& event) {
  CHECK(event.has_frame_rate_event());
  return event.frame_rate_event().event_code();
}

std::string FrameRateEventLogger::Component(const Event& event) {
  CHECK(event.has_frame_rate_event());
  return event.frame_rate_event().component();
}

int64_t FrameRateEventLogger::IntValue(const Event& event) {
  CHECK(event.has_frame_rate_event());
  return event.frame_rate_event().frames_per_1000_seconds();
}

Status FrameRateEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.metric());
  const auto& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->frame_rate_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

Status FrameRateEventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                                         const EventRecord& event_record) {
  switch (report.report_type()) {
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      return event_aggregator()->AddFrameRateEvent(report.id(), event_record);
    }
    default:
      return kOK;
  }
}

////////////// MemoryUsageEventLogger method implementations ///////////////////
const RepeatedField<uint32_t>& MemoryUsageEventLogger::EventCodes(const Event& event) {
  CHECK(event.has_memory_usage_event());
  return event.memory_usage_event().event_code();
}

std::string MemoryUsageEventLogger::Component(const Event& event) {
  CHECK(event.has_memory_usage_event());
  return event.memory_usage_event().component();
}

int64_t MemoryUsageEventLogger::IntValue(const Event& event) {
  CHECK(event.has_memory_usage_event());
  return event.memory_usage_event().bytes();
}

Status MemoryUsageEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.metric());
  const auto& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->memory_usage_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

Status MemoryUsageEventLogger::MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                                           const EventRecord& event_record) {
  switch (report.report_type()) {
    case ReportDefinition::PER_DEVICE_NUMERIC_STATS:
    case ReportDefinition::PER_DEVICE_HISTOGRAM: {
      return event_aggregator()->AddMemoryUsageEvent(report.id(), event_record);
    }
    default:
      return kOK;
  }
}

///////////// IntHistogramEventLogger method implementations ///////////////////

Status IntHistogramEventLogger::ValidateEvent(const EventRecord& event_record) {
  CHECK(event_record.event()->has_int_histogram_event());
  const auto& int_histogram_event = event_record.event()->int_histogram_event();
  CHECK(event_record.metric());
  const auto& metric = *(event_record.metric());

  auto status = ValidateEventCodes(metric, int_histogram_event.event_code(),
                                   event_record.project_context()->FullMetricName(metric));
  if (status != kOK) {
    return status;
  }

  if (!metric.has_int_buckets()) {
    LOG(ERROR) << "Invalid Cobalt config: Metric "
               << event_record.project_context()->FullMetricName(metric)
               << " does not have an |int_buckets| field set.";
    return kInvalidConfig;
  }
  const auto& int_buckets = metric.int_buckets();
  uint32_t num_valid_buckets;
  switch (int_buckets.buckets_case()) {
    case IntegerBuckets::kExponential:
      num_valid_buckets = int_buckets.exponential().num_buckets();
      break;
    case IntegerBuckets::kLinear:
      num_valid_buckets = int_buckets.linear().num_buckets();
      break;
    case IntegerBuckets::BUCKETS_NOT_SET:
      LOG(ERROR) << "Invalid Cobalt config: Metric "
                 << event_record.project_context()->FullMetricName(metric)
                 << " has an invalid |int_buckets| field. Either exponential "
                    "or linear buckets must be specified.";
      return kInvalidConfig;
  }

  // In addition to the specified num_buckets, there are the underflow and
  // overflow buckets.
  num_valid_buckets += 2;

  size_t num_provided_buckets = int_histogram_event.buckets_size();
  for (auto i = 0u; i < num_provided_buckets; i++) {
    if (int_histogram_event.buckets(i).index() >= num_valid_buckets) {
      LOG(ERROR) << "The provided histogram is invalid. The index value of "
                 << int_histogram_event.buckets(i).index() << " in position " << i
                 << " is out of bounds for Metric "
                 << event_record.project_context()->FullMetricName(metric) << ".";
      return kInvalidArguments;
    }
  }

  return kOK;
}

Encoder::Result IntHistogramEventLogger::MaybeEncodeImmediateObservation(
    const ReportDefinition& report, bool may_invalidate, EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "IntHistogramEventLogger::MaybeEncodeImmediateObservation");
  const MetricDefinition& metric = *(event_record->metric());
  const Event& event = *(event_record->event());
  CHECK(event.has_int_histogram_event());
  auto* int_histogram_event = event_record->event()->mutable_int_histogram_event();
  switch (report.report_type()) {
    // Each report type has its own logic for generating immediate
    // observations.
    case ReportDefinition::INT_RANGE_HISTOGRAM: {
      HistogramPtr histogram = std::make_unique<RepeatedPtrField<HistogramBucket>>();
      if (may_invalidate) {
        // We move the buckets out of |int_histogram_event| thereby
        // invalidating that variable.
        histogram->Swap(int_histogram_event->mutable_buckets());
      } else {
        histogram->CopyFrom(int_histogram_event->buckets());
      }
      return encoder()->EncodeHistogramObservation(
          event_record->project_context()->RefMetric(&metric), &report, event.day_index(),
          int_histogram_event->event_code(), int_histogram_event->component(),
          std::move(histogram));
    }

    default:
      return BadReportType(event_record->project_context()->FullMetricName(metric), report);
  }
}

///////////// OccurrenceEventLogger method implementations //////////////////////////

Status OccurrenceEventLogger::ValidateEvent(const EventRecord& event_record) {
  if (!event_record.event()->has_occurrence_event()) {
    LOG(ERROR) << "The provided event is invalid, expected it to contain an event type of "
                  "OccurrenceEvent, but instead found "
               << event_record.event()->type_case();
    return kInvalidArguments;
  }
  if (event_record.metric() == nullptr) {
    LOG(ERROR) << "The provided event is missing a metric";
    return kInvalidArguments;
  }
  const MetricDefinition& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->occurrence_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

///////////// IntegerEventLogger method implementations //////////////////////////

Status IntegerEventLogger::ValidateEvent(const EventRecord& event_record) {
  if (!event_record.event()->has_integer_event()) {
    LOG(ERROR) << "The provided event is invalid, expected it to contain an event type of "
                  "IntegerEvent, but instead found "
               << event_record.event()->type_case();
    return kInvalidArguments;
  }
  if (event_record.metric() == nullptr) {
    LOG(ERROR) << "The provided event is missing a metric";
    return kInvalidArguments;
  }
  const MetricDefinition& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->integer_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

///////////// IntegerHistogramEventLogger method implementations //////////////////////////

Status IntegerHistogramEventLogger::ValidateEvent(const EventRecord& event_record) {
  if (!event_record.event()->has_integer_histogram_event()) {
    LOG(ERROR) << "The provided event is invalid, expected it to contain an event type of "
                  "IntegerHistogramEvent, but instead found "
               << event_record.event()->type_case();
    return kInvalidArguments;
  }
  const IntegerHistogramEvent& integer_histogram_event =
      event_record.event()->integer_histogram_event();
  if (event_record.metric() == nullptr) {
    LOG(ERROR) << "The provided event is missing a metric";
    return kInvalidArguments;
  }
  const MetricDefinition& metric = *(event_record.metric());

  auto status = ValidateEventCodes(metric, integer_histogram_event.event_code(),
                                   event_record.project_context()->FullMetricName(metric));
  if (status != kOK) {
    return status;
  }

  if (!metric.has_int_buckets()) {
    LOG(ERROR) << "Invalid Cobalt config: Metric "
               << event_record.project_context()->FullMetricName(metric)
               << " does not have an |int_buckets| field set.";
    return kInvalidConfig;
  }
  const IntegerBuckets& int_buckets = metric.int_buckets();
  uint32_t num_valid_buckets;
  switch (int_buckets.buckets_case()) {
    case IntegerBuckets::kExponential:
      num_valid_buckets = int_buckets.exponential().num_buckets();
      break;
    case IntegerBuckets::kLinear:
      num_valid_buckets = int_buckets.linear().num_buckets();
      break;
    case IntegerBuckets::BUCKETS_NOT_SET:
      LOG(ERROR) << "Invalid Cobalt config: Metric "
                 << event_record.project_context()->FullMetricName(metric)
                 << " has an invalid |int_buckets| field. Either exponential "
                    "or linear buckets must be specified.";
      return kInvalidConfig;
  }

  // In addition to the specified num_buckets, there are the underflow and
  // overflow buckets.
  num_valid_buckets += 2;

  size_t num_provided_buckets = integer_histogram_event.buckets_size();
  for (auto i = 0u; i < num_provided_buckets; ++i) {
    if (integer_histogram_event.buckets(i).index() >= num_valid_buckets) {
      LOG(ERROR) << "The provided histogram is invalid. The index value of "
                 << integer_histogram_event.buckets(i).index() << " in position " << i
                 << " is out of bounds for Metric "
                 << event_record.project_context()->FullMetricName(metric) << ".";
      return kInvalidArguments;
    }
  }

  return kOK;
}

///////////// StringEventLogger method implementations //////////////////////////

Status StringEventLogger::ValidateEvent(const EventRecord& event_record) {
  if (!event_record.event()->has_string_event()) {
    LOG(ERROR) << "The provided event is invalid, expected it to contain an event type of "
                  "StringEvent, but instead found "
               << event_record.event()->type_case();
    return kInvalidArguments;
  }
  if (event_record.metric() == nullptr) {
    LOG(ERROR) << "The provided event is missing a metric";
    return kInvalidArguments;
  }
  const MetricDefinition& metric = *(event_record.metric());
  return ValidateEventCodes(metric, event_record.event()->string_event().event_code(),
                            event_record.project_context()->FullMetricName(metric));
}

/////////////// CustomEventLogger method implementations ///////////////////////

Status CustomEventLogger::ValidateEvent(const EventRecord& /*event_record*/) {
  // TODO(ninai) Add proto validation.
  return kOK;
}

Encoder::Result CustomEventLogger::MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                                   bool may_invalidate,
                                                                   EventRecord* event_record) {
  TRACE_DURATION("cobalt_core", "CustomEventLogger::MaybeEncodeImmediateObservation");
  const MetricDefinition& metric = *(event_record->metric());
  const Event& event = *(event_record->event());
  CHECK(event.has_custom_event());
  auto* custom_event = event_record->event()->mutable_custom_event();
  switch (report.report_type()) {
    // Each report type has its own logic for generating immediate
    // observations.
    case ReportDefinition::CUSTOM_RAW_DUMP: {
      if (!custom_event->serialized_proto().empty()) {
        auto serialized_proto = std::make_unique<std::string>();
        if (may_invalidate) {
          serialized_proto->swap(*(custom_event->mutable_serialized_proto()));
        } else {
          *serialized_proto = custom_event->serialized_proto();
        }
        return encoder()->EncodeSerializedCustomObservation(
            event_record->project_context()->RefMetric(&metric), &report, event.day_index(),
            std::move(serialized_proto));
      }
      EventValuesPtr event_values =
          std::make_unique<google::protobuf::Map<std::string, CustomDimensionValue>>();
      if (may_invalidate) {
        // We move the contents out of |custom_event| thereby invalidating
        // that variable.
        event_values->swap(*(custom_event->mutable_values()));
      } else {
        event_values = std::make_unique<google::protobuf::Map<std::string, CustomDimensionValue>>(
            custom_event->values());
      }
      return encoder()->EncodeCustomObservation(event_record->project_context()->RefMetric(&metric),
                                                &report, event.day_index(),
                                                std::move(event_values));
    }

    default:
      return BadReportType(event_record->project_context()->FullMetricName(metric), report);
  }
}

}  // namespace cobalt::logger::internal
