// 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/logger/status.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 ::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)
      : encoder_(encoder),
        event_aggregator_(event_aggregator),
        local_aggregation_(local_aggregation),
        observation_writer_(observation_writer),
        system_data_(system_data) {}

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

  // 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|.
  static void 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_;
};

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