// Copyright 2020 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_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATION_H_
#define COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATION_H_

#include "src/lib/util/clock.h"
#include "src/lib/util/file_system.h"
#include "src/local_aggregation_1_1/aggregation_procedures/aggregation_procedure.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/local_aggregate_storage.h"
#include "src/local_aggregation_1_1/observation_generator.h"
#include "src/logger/event_record.h"
#include "src/logger/logger_interface.h"
#include "src/logger/observation_writer.h"
#include "src/logger/project_context_factory.h"
#include "src/pb/metadata_builder.h"
#include "src/public/cobalt_config.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/public/lib/status.h"
#include "src/system_data/system_data.h"

namespace cobalt::local_aggregation {

// LocalAggregation is the top-level object responsible for scheduling and managing the current
// aggregated observations.
class LocalAggregation {
 public:
  // Constructor for LocalAggregation
  //
  // |cfg|: A reference to the CobaltConfig used to construct the CobaltService.
  // |global_project_context_factory|: The current global registry.
  // |system_data|: Used by the ObservationGenerator to get the current SystemProfile.
  // |metadata_builder|: Used to construct LocalAggregateStorage.
  // |fs|: An instance of util::FileSystem
  // |observation_writer|: An implementation of the ObservationWriter interface.
  // |civil_time_converter|: Converts a `time_point` to a civil time for a given time zone.
  LocalAggregation(const CobaltConfig &cfg,
                   const logger::ProjectContextFactory *global_project_context_factory,
                   system_data::SystemDataInterface &system_data, MetadataBuilder &metadata_builder,
                   util::FileSystem &fs, const logger::ObservationWriter &observation_writer,
                   util::CivilTimeConverterInterface *civil_time_converter);

  // Start should be called when the system is ready to start the background process for generating
  // observations based on the aggregated events.
  //
  // |clock|: An implementation of the SystemClockInterface. The caller should make sure that this
  // clock is an accurate representation of the current system time before calling Start.
  void Start(std::unique_ptr<util::SystemClockInterface> clock);

  // ShutDown stops all background process and waits until they end.
  void ShutDown();

  // GenerateAggregatedObservations forces the observation generator to run a single observation
  // generation pass. This should not be called if Start() has been called previously. The
  // observation generator creates observations for aggregation periods which have ended by
  // `system_time` and for which observations have not already been generated.
  Status GenerateAggregatedObservations(std::chrono::system_clock::time_point system_time);

  // AddEvent adds an EventRecord to local aggregation. The |event_timestamp| is used as the
  // time the event occurred at.
  Status AddEvent(const logger::EventRecord &event_record,
                  const std::chrono::system_clock::time_point &event_timestamp);

  // Disable allows enabling/disabling LocalAggregation. When aggregation is disabled, AddEvent()
  // will return kOk, but the event will not be stored.
  void Disable(bool is_disabled);

  // IsDisabled returns true if LocalAggregation is disabled and should ignore incoming events
  // by returning kOk and not storing the data.
  bool IsDisabled() const { return is_disabled_; }

  void DeleteData() { aggregate_storage_->DeleteData(); }

  void ResetInternalMetrics(logger::InternalMetrics *internal_metrics) {
    aggregate_storage_->ResetInternalMetrics(internal_metrics);
  }

  // CanStore will return true if either:
  // 1. The project is currently storing less than per_project_reserved_bytes
  // 2. The project is over per_project_reserved_bytes, but there is room in the "Slush" storage.
  bool CanStore(lib::ProjectIdentifier project) const;

  // Returns the size of the "Slush" storage. This should be the total_capacity_bytes minus (number
  // of projects * per_project_reserved_bytes).
  int64_t SlushSize() const;

  // Returns the amount of data used that exceeds each projects' per_project_reserved_bytes.
  int64_t SlushUsed() const;

 private:
  const logger::ProjectContextFactory *global_project_context_factory_;
  std::unique_ptr<LocalAggregateStorage> aggregate_storage_;
  ObservationGenerator observation_generator_;
  std::unique_ptr<util::SystemClockInterface> system_clock_;
  bool is_disabled_ = false;
  StorageQuotas storage_quotas_;
};

}  // namespace cobalt::local_aggregation

#endif  // COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATION_H_
