// Copyright 2019 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_UNDATED_EVENT_MANAGER_H_
#define COBALT_SRC_LOGGER_UNDATED_EVENT_MANAGER_H_

#include <queue>
#include <string>

#include "src/lib/util/clock.h"
#include "src/local_aggregation/event_aggregator.h"
#include "src/local_aggregation_1_1/local_aggregation.h"
#include "src/logger/encoder.h"
#include "src/logger/internal_metrics.h"
#include "src/logger/logger_interface.h"
#include "src/logger/observation_writer.h"
#include "src/logger/project_context.h"
#include "src/logger/status.h"

namespace cobalt::logger {

// A container for an EventRecord and the time/context when it was logged.
struct SavedEventRecord {
  // The steady clock time when the event occurred.
  const std::chrono::steady_clock::time_point monotonic_time;
  // The event that occurred.
  std::unique_ptr<EventRecord> event_record;
};

constexpr int32_t kDefaultMaxSavedEvents = 10000;

// UndatedEventManager manages events without timestamps while the clock is inaccurate.
//
// While the system clock is unreliable, Cobalt Loggers will pass incoming Events to the
// UndatedEventManager for interim storage. No locally aggregated observations will be generated
// during this time. Buffered events will be stored in memory with the monotonic (steady) time they
// occurred at, and dropped if a reboot occurs before a clock sync or if a storage quota is reached.
//
// When the UndatedEventManager is notified that the system clock is reliable, it will use the
// current offset between the (now accurate) system clock and the monotonic (steady) clock to assign
// a date to each buffered event. The events will then moved back into the main logging path, to be
// either aggregated on-device or formed into observations.
//
// There should be one instance of UndatedEventManager across all Loggers.
class UndatedEventManager {
 public:
  // Constructor
  //
  // The non-optional parameters are needed to be able to construct EventLoggers.
  // See the EventLogger constructor for their use.
  //
  // |max_saved_event_memory| The maximum amount of memory to use to save events. When this limit is
  // reached, old events are dropped to make room for new events.
  //
  // |steady_clock| An optional steady clock to use to record the monotonic time of saved events.
  // Primarily for testing.
  UndatedEventManager(const Encoder* encoder, local_aggregation::EventAggregator* event_aggregator,
                      local_aggregation::LocalAggregation* local_aggregation,
                      ObservationWriter* observation_writer,
                      system_data::SystemDataInterface* system_data,
                      int32_t max_saved_events = kDefaultMaxSavedEvents);

  // Saves the fact that an event has occurred.
  //
  // |event_record| The event that occurred.
  Status Save(std::unique_ptr<EventRecord> event_record);

  // Flush all the saved events now that the system clock is accurate.
  //
  // |system_clock| The system clock that can now be used to log events.
  // |internal_logger| The Logger instance used to send metrics about Cobalt to Cobalt.
  Status Flush(util::SystemClockInterface* system_clock, LoggerInterface* internal_logger);

  // Get the current number of events that are being saved.
  int NumSavedEvents() const;

 private:
  friend class UndatedEventManagerTest;  // for testing

  void SetSteadyClock(util::SteadyClockInterface* steady_clock) {
    steady_clock_.reset(steady_clock);
  }

  Status FlushSavedRecord(std::unique_ptr<SavedEventRecord> saved_record,
                          const std::chrono::system_clock::time_point& reference_system_time,
                          const std::chrono::steady_clock::time_point& reference_monotonic_time);

  // Used only to construct EventLogger instances.
  const Encoder* encoder_;
  local_aggregation::EventAggregator* event_aggregator_;
  local_aggregation::LocalAggregation* local_aggregation_;
  const ObservationWriter* observation_writer_;
  const system_data::SystemDataInterface* system_data_;

  size_t max_saved_events_;

  // A monotonic (steady) clock for tracking event time when the system clock is inaccurate.
  std::unique_ptr<util::SteadyClockInterface> steady_clock_;

  // Guards access to saved_records_ and the other related fields.
  struct SavedRecordsFields {
    // FIFO queue of SavedEventRecords to process once the clock is accurate.
    std::deque<std::unique_ptr<SavedEventRecord>> saved_records_;

    // Mapping of identifiers of ProjectContexts to the stats for them.
    std::map<std::pair<uint32_t, uint32_t>, int64_t> num_events_cached_;
    std::map<std::pair<uint32_t, uint32_t>, int64_t> num_events_dropped_;

    // Whether Flush() has already been called on this object.
    bool flushed = false;

    // If |flushed_| is true, these will contain the reference clock values at the time of the
    // flush.
    std::chrono::system_clock::time_point reference_system_time_;
    std::chrono::steady_clock::time_point reference_monotonic_time_;
  };
  util::RWProtectedFields<SavedRecordsFields> protected_saved_records_fields_;
};

}  // namespace cobalt::logger

#endif  // COBALT_SRC_LOGGER_UNDATED_EVENT_MANAGER_H_
