// Copyright 2017 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_ANALYZER_REPORT_MASTER_REPORT_SCHEDULER_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_SCHEDULER_H_

#include <atomic>
#include <memory>
#include <string>

#include "analyzer/report_master/report_history_cache.h"
#include "analyzer/report_master/report_master_service.h"
#include "analyzer/store/report_store.h"
#include "config/report_config.h"
#include "util/clock.h"

namespace cobalt {
namespace analyzer {

// An abstract interface that allows the real ReportMasterService to be
// mocked out in unit tests of the ReportScheduler.
class ReportStarterInterface {
 public:
  virtual grpc::Status StartReport(const ReportConfig& report_config,
                                   uint32_t first_day_index,
                                   uint32_t last_day_index,
                                   const std::string& export_name,
                                   bool in_store, ReportId* report_id_out) = 0;

  virtual ~ReportStarterInterface() = default;
};

// Forward declare ReportMasterService because report_master_serivce.h and
// report_scheduler.h include each other.
class ReportMasterService;

// An implementation of ReportStarterInterface that delegates to an instance
// of ReportMasterService. This is the implementation used in production.
class ReportStarter : public ReportStarterInterface {
 public:
  explicit ReportStarter(ReportMasterService* report_master_service);
  virtual ~ReportStarter() = default;
  grpc::Status StartReport(const ReportConfig& report_config,
                           uint32_t first_day_index, uint32_t last_day_index,
                           const std::string& export_name, bool in_store,
                           ReportId* report_id_out) override;

 private:
  ReportMasterService* report_master_service_;  // not owned
};

// ReportScheduler periodically runs reports according to their configured
// schedules.
//
// A ReportConfig contains a ReportSchedulingConfig that contains two fields
// that influence report scheduling:
// |aggreggation_epoch_type| and |report_finalization_days|.
//
// There are three aggregation epoch types: DAY, WEEK and MONTH. The DAY type
// means that each report aggregates the set of Observations from a single day,
// and that the report is run daily. Since WEEK and MONTH reports are not
// currently implemented, the remainder of this description will assume that the
// aggregation epoch type is DAY.
//
// Each Observation sent from an Encoder client is tagged with a |day_index|
// indicating which day the Observation corresponds to. The |day_index|
// is computed based on a time zone specified in the MetricConfig--it is not
// necessarily the local time zone of the Encoder client. The ReportScheduler
// running within the ReportMaster always uses the UTC time zone to compute
// the current day index at report generation time.
//
// The |report_finalization_days| field of a ReportConfig indicates how many
// days to wait for Observations to arrive before considering a report
// finalized. The ReportScheduler will regenerate a report multiple times
// to allow  additional observations to trickle in up to several days after the
// report period ends. This is important for several reasons: (a) The client
// and server may use different time zones (b) The client may be temporarily
// offline (c) the Shuffler may be configured to intentionally add a delay.
// |report_finalization_days| controls the number after days after the
// report day before the ReportScheduler considers the report to be finalized.
//
// The FLAG |daily_report_makeup_days| is an important parameter in the
// scheduling algorithm. This is the number of days in the past that the
// ReportScheduler will look to find instances of reports that should have been
// executed but were not. By default its value is 30.
//
// The scheduling algorithm is as follows. A single background thread called
// the scheduler thread loops forever, sleeping for a while
// (by default 17 minutes) and then waking up and iteratively processing all of
// the registered report configurations. Processing of a single report
// configuration X of Day type proceeds as follows. First the current day index
// is computed relative to the UTC timezone. Next we consider the interval
// of day indices [a, b] where b = the current day index and where
// a = b - FLAGS_daily_report_makeup_days. For each day index d in [a, b]
// we ask if we should run a report for report config X for day d and if the
// answer is yes then we do run such a report. The way we determine whether
// or not we should run a report depends on whether or not report config X
// for day d has already been finalized. If d <= b - report_finalization_days
// then the report is considered finalized. In this case we will only run a
// report for day d if there is not already a successfully completed report
// for day d. Also we keep track of whether or not we have already started
// a report for report config X for day d that has not yet finished running.
// In this case also we will not start another one. If
// instead d > b - report_finalization_days then the report for report config
// X for day d is considered not yet finalized. In this case we will always
// run another such report unless one was started earlier and is not yet
// finished running.
//
// Usage: Construct a ReportScheduler and then invoke Start(), which returns
// immediately. ReportScheduler has a background scheduler thread that runs
// until the instance of ReportScheduler is destructed.
class ReportScheduler {
 public:
  // |report_registry| contains the registered ReportConfigs. This determines
  // which reports to run and their schedules. This data is "live": The
  // registered ReportConfigs are re-read periodically (based on the parameter
  // |sleep_interval|).
  //
  // |report_store| is used to query the history of generated reports in order
  // to determine whether a report needs to be run.
  //
  // |report_starter| is used to start the asynchronous generation of reports.
  //
  // |sleep_interval| determines the frequency with which ReportScheduler
  // re-reads the registered reports in |analyzer_config| and checks
  // to see if it is time to generate a report. Optional, defaults to 17
  // minutes.
  ReportScheduler(std::shared_ptr<config::AnalyzerConfigManager> config_manager,
                  std::shared_ptr<store::ReportStore> report_store,
                  std::shared_ptr<ReportStarterInterface> report_starter,
                  std::chrono::milliseconds sleep_interval =
                      std::chrono::milliseconds(1000 * 60 * 17));

  // The destructor will stop the scheduler thread and wait for it to stop
  // before exiting.
  ~ReportScheduler();

  // Starts the scheduler thread. Destruct this object to stop the thread.
  // This method must be invoked exactly once.
  void Start();

  void SetClockForTesting(std::shared_ptr<util::ClockInterface> clock) {
    clock_ = clock;
  }

 private:
  friend class ReportSchedulerTest;

  // The main function that runs in the ReportScheduler's scheduler thread.
  // Loops forever, repeatedly invoking Sleep() and ProcessReports() until
  // shut_down_ is set true.
  void Run();

  // Sleeps for |sleep_interval_| time, or until |shut_down_| is set true.
  void Sleep();

  // Returns the current day index relative to UTC at the current time.
  uint32_t CurrentDayIndex();

  // Iterates through all of the registered report configs, invoking
  // ProcessOneReport() on each.
  void ProcessReports();

  // Invokes ProcessDailyReport, ProcessWeeklyReport or ProcessMonthlyReport
  // as appropriate.
  void ProcessOneReport(const ReportConfig& report_config,
                        uint32_t current_day_index);

  // Process one daily report. For each day over the previous 31 days
  // (this may be overridden by FLAGS_daily_report_makeup_days), invokes
  // ShouldStartDailyReportNow() and if that method returns true then invokes
  // StartReportNow().
  void ProcessDailyReport(const ReportConfig& report_config,
                          uint32_t current_day_index);

  // Not currently implemented.
  void ProcessWeeklyReport(const ReportConfig& report_config,
                           uint32_t current_day_index);
  // Not currently implemented.
  void ProcessMonthlyReport(const ReportConfig& report_config,
                            uint32_t current_day_index);

  // Determines if a report for the given ReportConfig should be run
  // for the given day_index assume the current day index is given
  // by |current_day_index|.
  bool ShouldStartDailyReportNow(const ReportConfig& report_config,
                                 uint32_t day_index,
                                 uint32_t current_day_index);

  // Uses the ReportStarter passed in to the constructor to start the
  // specified report for the specified interval of days.
  void StartReportNow(const ReportConfig& report_config,
                      uint32_t first_day_index, uint32_t last_day_index);

  // Generates the name by which the report with the specified parameters
  // should be exported.
  std::string ReportExportName(const ReportConfig& report_config,
                               uint32_t first_day_index,
                               uint32_t last_day_index);

  // The clock is abstracted so that friend tests can set a non-system clock.
  std::shared_ptr<util::ClockInterface> clock_;

  // The "Run()" method runs in this thread.
  std::thread scheduler_thread_;

  std::shared_ptr<config::AnalyzerConfigManager> config_manager_;
  std::shared_ptr<ReportStarterInterface> report_starter_;
  std::unique_ptr<ReportHistoryCache> report_history_;

  // How much time to sleep during the Sleep() method.
  std::chrono::milliseconds sleep_interval_;

  // Protects  shut_down_ and shut_down_notifier_
  std::mutex mutex_;

  std::atomic<bool> shut_down_;

  std::condition_variable shut_down_notifier_;  // Protected by mutex_.
};

}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_REPORT_MASTER_REPORT_SCHEDULER_H_
