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

#ifndef COBALT_SRC_LOGGER_EVENT_LOGGERS_H_
#define COBALT_SRC_LOGGER_EVENT_LOGGERS_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "src/local_aggregation/event_aggregator.h"
#include "src/local_aggregation_1_1/local_aggregation.h"
#include "src/logger/encoder.h"
#include "src/logger/event_record.h"
#include "src/logger/observation_writer.h"
#include "src/logger/project_context.h"
#include "src/logging.h"
#include "src/pb/event.pb.h"
#include "src/pb/observation.pb.h"
#include "src/public/lib/status.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/report_definition.pb.h"
#include "src/tracing.h"

namespace cobalt::logger::internal {

using ::google::protobuf::RepeatedField;

// EventLogger is an abstract interface used internally in logger.cc to
// dispatch logging logic based on Metric type. Below we create subclasses
// of EventLogger for each of several Metric types.
class EventLogger {
 public:
  EventLogger(const Encoder& encoder, local_aggregation::EventAggregator& event_aggregator,
              local_aggregation::LocalAggregation* local_aggregation,
              const ObservationWriter* observation_writer,
              const system_data::SystemDataInterface* system_data,
              util::CivilTimeConverterInterface* civil_time_converter)
      : encoder_(encoder),
        event_aggregator_(event_aggregator),
        local_aggregation_(local_aggregation),
        observation_writer_(observation_writer),
        system_data_(system_data),
        civil_time_converter_(civil_time_converter) {}

  virtual ~EventLogger() = default;

  // Factory for creating an appropriate EventLogger subclass for the type of metric being logged.
  //
  // |metric_type| is the type of metric to be logged with the created event logger.
  //
  // The remaining parameters are passed to the EventLogger constructor.
  static std::unique_ptr<EventLogger> Create(
      MetricDefinition::MetricType metric_type, const Encoder& encoder,
      local_aggregation::EventAggregator& event_aggregator,
      local_aggregation::LocalAggregation* local_aggregation,
      const ObservationWriter* observation_writer,
      const system_data::SystemDataInterface* system_data,
      util::CivilTimeConverterInterface* civil_time_converter);

  // Finds the Metric with the given ID. Expects that this has type
  // |expected_metric_type|. If not logs an error and returns.
  // If so then logs the Event specified by |event_record| to Cobalt.
  // The |event_timestamp| is recorded as the time the event occurred at.
  Status Log(std::unique_ptr<EventRecord> event_record,
             const std::chrono::system_clock::time_point& event_timestamp);

  // Prepare an event for logging, and validate that it is suitable.
  Status PrepareAndValidateEvent(uint32_t metric_id, MetricDefinition::MetricType expected_type,
                                 EventRecord* event_record);

 protected:
  const Encoder& encoder() { return encoder_; }
  local_aggregation::EventAggregator& event_aggregator() { return event_aggregator_; }
  local_aggregation::LocalAggregation* local_aggregation() { return local_aggregation_; }

  static Encoder::Result BadReportType(const std::string& full_metric_name,
                                       const ReportDefinition& report);

  // Validates the supplied event_codes against the defined metric dimensions
  // in the MetricDefinition.
  virtual Status ValidateEventCodes(const MetricDefinition& metric,
                                    const RepeatedField<uint32_t>& event_codes,
                                    const std::string& full_metric_name);

 private:
  friend class EventLoggersAddEventTest;
  friend class EventLoggersLocalAggregationTest;

  // Validate that the event is suitable for logging.
  //
  // Most of the event validation should be done here, as this occurs at the time
  // the event occurs.
  virtual Status ValidateEvent(const EventRecord& event_record);

  // Finishes setting up the event using |event_timestamp| as the time the event occurred at,
  // and then performs any final validation of the |event_record|.
  Status FinalizeEvent(EventRecord* event_record,
                       const std::chrono::system_clock::time_point& event_timestamp);

  // Given an EventRecord and a ReportDefinition, determines whether or not
  // the Event should be used to update a local aggregation and if so passes
  // the Event to the Local Aggregator.
  virtual Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                             const EventRecord& event_record);

  // Given an EventRecord and a ReportDefinition, determines whether or not
  // the Event should be used to generate an immediate Observation and if so
  // does generate one and writes it to the Observation Store.
  //
  // |may_invalidate| indicates that the implementation is allowed to invalidate
  // |event_record|. This should be set true only when it is known that
  // |event_record| is no longer needed. Setting this true allows the data in
  // |event_record| to be moved rather than copied.
  Status MaybeGenerateImmediateObservation(const ReportDefinition& report, bool may_invalidate,
                                           EventRecord* event_record);

  // Given an EventRecord and a ReportDefinition, determines whether or not
  // the Event should be used to generate an immediate Observation and if so
  // does generate one. This method is invoked by
  // MaybeGenerateImmediateObservation().
  //
  // |may_invalidate| indicates that the implementation is allowed to invalidate
  // |event_record|. This should be set true only when it is known that
  // |event_record| is no longer needed. Setting this true allows the data in
  // |event_record| to be moved rather than copied.
  virtual Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                          bool may_invalidate,
                                                          EventRecord* event_record);

  [[nodiscard]] virtual bool IsOnePointOne() const { return false; }

  // Traces an |event_record| into a string if the metric is tagged with
  // also_log_locally. If not, it will return the empty string.
  static std::string TraceEvent(const EventRecord& event_record);

  // Logs a trace of an |event_record| that failed to be logged to Cobalt.
  //
  // |status| The status code reported to the user.
  // |event_record| The event_record associated with the event.
  // |trace| The string output from TraceEvent().
  // |report| Information about the report for which the logging failed.
  static void TraceLogFailure(const Status& status, const EventRecord& event_record,
                              const std::string& trace, const ReportDefinition& report);

  // Logs a trace of an |event_record| that successfully logged to Cobalt.
  //
  // |event_record| The event_record associated with the event.
  // |trace| The string output from TraceEvent().
  static void TraceLogSuccess(const EventRecord& event_record, const std::string& trace);

  const Encoder& encoder_;
  local_aggregation::EventAggregator& event_aggregator_;
  local_aggregation::LocalAggregation* local_aggregation_;
  const ObservationWriter* observation_writer_;
  const system_data::SystemDataInterface* system_data_;
  util::CivilTimeConverterInterface* civil_time_converter_;
};

// Implementation of EventLogger for metrics of type EVENT_OCCURRED.
class EventOccurredEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~EventOccurredEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                  bool may_invalidate,
                                                  EventRecord* event_record) override;
  Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                     const EventRecord& event_record) override;
};

// Implementation of EventLogger for metrics of type EVENT_COUNT.
class EventCountEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~EventCountEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                  bool may_invalidate,
                                                  EventRecord* event_record) override;
  Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                     const EventRecord& event_record) override;
};

// Implementation of EventLogger for all of the numerical performance metric
// types. This is an abstract class. There are subclasses below for each
// metric type.
class IntegerPerformanceEventLogger : public EventLogger {
 protected:
  using EventLogger::EventLogger;
  ~IntegerPerformanceEventLogger() override = default;

 private:
  Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                  bool may_invalidate,
                                                  EventRecord* event_record) override;
  virtual const RepeatedField<uint32_t>& EventCodes(const Event& event) = 0;
  virtual std::string Component(const Event& event) = 0;
  virtual int64_t IntValue(const Event& event) = 0;
};

// Implementation of EventLogger for metrics of type ELAPSED_TIME.
class ElapsedTimeEventLogger : public IntegerPerformanceEventLogger {
 public:
  using IntegerPerformanceEventLogger::IntegerPerformanceEventLogger;
  ~ElapsedTimeEventLogger() override = default;

 private:
  const RepeatedField<uint32_t>& EventCodes(const Event& event) override;
  std::string Component(const Event& event) override;
  int64_t IntValue(const Event& event) override;
  Status ValidateEvent(const EventRecord& event_record) override;
  Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                     const EventRecord& event_record) override;
};

// Implementation of EventLogger for metrics of type FRAME_RATE.
class FrameRateEventLogger : public IntegerPerformanceEventLogger {
 public:
  using IntegerPerformanceEventLogger::IntegerPerformanceEventLogger;
  ~FrameRateEventLogger() override = default;

 private:
  const RepeatedField<uint32_t>& EventCodes(const Event& event) override;
  std::string Component(const Event& event) override;
  int64_t IntValue(const Event& event) override;
  Status ValidateEvent(const EventRecord& event_record) override;
  Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                     const EventRecord& event_record) override;
};

// Implementation of EventLogger for metrics of type MEMORY_USAGE.
class MemoryUsageEventLogger : public IntegerPerformanceEventLogger {
 public:
  using IntegerPerformanceEventLogger::IntegerPerformanceEventLogger;
  ~MemoryUsageEventLogger() override = default;

 private:
  const RepeatedField<uint32_t>& EventCodes(const Event& event) override;
  std::string Component(const Event& event) override;
  int64_t IntValue(const Event& event) override;
  Status ValidateEvent(const EventRecord& event_record) override;
  Status MaybeUpdateLocalAggregation(const ReportDefinition& report,
                                     const EventRecord& event_record) override;
};

// Implementation of EventLogger for metrics of type INT_HISTOGRAM.
class IntHistogramEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~IntHistogramEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                  bool may_invalidate,
                                                  EventRecord* event_record) override;
};

// Implementation of EventLogger for metrics of type OCCURRENCE.
class OccurrenceEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~OccurrenceEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  [[nodiscard]] bool IsOnePointOne() const override { return true; }
};

// Implementation of EventLogger for metrics of type INTEGER.
class IntegerEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~IntegerEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  [[nodiscard]] bool IsOnePointOne() const override { return true; }
};

// Implementation of EventLogger for metrics of type INTEGER_HISTOGRAM.
class IntegerHistogramEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~IntegerHistogramEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  [[nodiscard]] bool IsOnePointOne() const override { return true; }
};

// Implementation of EventLogger for metrics of type STRING.
class StringEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~StringEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  [[nodiscard]] bool IsOnePointOne() const override { return true; }
};

// Implementation of EventLogger for metrics of type CUSTOM.
class CustomEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~CustomEventLogger() override = default;

 private:
  Status ValidateEvent(const EventRecord& event_record) override;
  Encoder::Result MaybeEncodeImmediateObservation(const ReportDefinition& report,
                                                  bool may_invalidate,
                                                  EventRecord* event_record) override;
};

}  // namespace cobalt::logger::internal

#endif  // COBALT_SRC_LOGGER_EVENT_LOGGERS_H_
