// 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/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/observation2.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,
              const ObservationWriter* observation_writer,
              const system_data::SystemDataInterface* system_data)
      : encoder_(encoder),
        event_aggregator_(event_aggregator),
        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,
                                             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_; }

  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;

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

  // Traces an |event_record| into a string if the metric is tagged with
  // also_log_locally. If not, it will return the empty string.
  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.
  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().
  void TraceLogSuccess(const EventRecord& event_record, const std::string& trace);

  const Encoder* encoder_;
  local_aggregation::EventAggregator* event_aggregator_;
  const ObservationWriter* observation_writer_;
  const system_data::SystemDataInterface* system_data_;
};

// Implementation of EventLogger for metrics of type EVENT_OCCURRED.
class OccurrenceEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~OccurrenceEventLogger() 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 CountEventLogger : public EventLogger {
 public:
  using EventLogger::EventLogger;
  ~CountEventLogger() 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 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_
