// 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_metrics| A (possible nullptr) instance of InternalMetrics.
  Status Flush(util::SystemClockInterface* system_clock, InternalMetrics* internal_metrics);

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