// 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/lib/util/status.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/observation_writer.h"
#include "src/logger/project_context_factory.h"
#include "src/pb/metadata_builder.h"
#include "src/public/cobalt_config.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.
  // |metadata_builder|: Used to construct ObservationMetadata.
  // |fs|: An instance of util::FileSystem
  // |observation_writer|: An implementation of the ObservationWriter interface.
  LocalAggregation(const CobaltConfig &cfg,
                   const logger::ProjectContextFactory *global_project_context_factory,
                   MetadataBuilder *metadata_builder, util::FileSystem *fs,
                   const logger::ObservationWriter *observation_writer);

  // 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.
  //
  // |utc| A TimeInfo for UTC based metrics. Can be created from a day_index using
  //       `TimeInfo::FromDayIndex(day_index)`
  // |local| A TimeInfo for LOCAL based metrics. Can be created from a day_index using
  //         `TimeInfo::FromDayIndex(day_index)`. (This may be set to the same value as utc in
  //         testing)
  util::Status GenerateAggregatedObservations(util::TimeInfo utc, util::TimeInfo local);

  // AddEvent adds an EventRecord to local aggregation.
  util::Status AddEvent(const logger::EventRecord &event_record);

  // 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(); }

 private:
  std::unique_ptr<LocalAggregateStorage> aggregate_storage_;
  MetadataBuilder *metadata_builder_;
  ObservationGenerator observation_generator_;
  std::unique_ptr<util::SystemClockInterface> system_clock_;
  bool is_disabled_ = false;
};

}  // namespace cobalt::local_aggregation

#endif  // COBALT_SRC_LOCAL_AGGREGATION_1_1_LOCAL_AGGREGATION_H_
