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

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_events| The maximum number of saved events. When this limit is reached, old events
  // are dropped to make room for new events.
  UndatedEventManager(const Encoder& encoder, local_aggregation::EventAggregator& event_aggregator,
                      local_aggregation::LocalAggregation& local_aggregation,
                      ObservationWriter& observation_writer,
                      system_data::SystemDataInterface& system_data,
                      util::CivilTimeConverterInterface* civil_time_converter,
                      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_;
  util::CivilTimeConverterInterface* civil_time_converter_;

  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_
