// Copyright 2016 The Chromium OS 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 POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_
#define POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_

#include <memory>
#include <string>

#include <base/callback.h>
#include <base/macros.h>
#include <base/time/time.h>
#include <base/timer/timer.h>

namespace power_manager {

class Clock;

// Non-instantiatable base class for logging activity. This contains members and
// testing code shared by all implementations.
class BaseActivityLogger {
 public:
  // Logging callback that can be replaced for testing.
  using LogCallback = base::Callback<void(const std::string&)>;

  Clock* clock_for_test() { return clock_.get(); }

  // Sets an alternate callback to be run to log messages.
  void SetLogCallbackForTest(LogCallback callback);

  // Returns the current delays of timers or empty deltas if they're stopped.
  base::TimeDelta GetStoppedTimerDelayForTest() const;
  base::TimeDelta GetOngoingTimerDelayForTest() const;

  // Triggers timers and returns true if they're running. Returns false if they
  // aren't.
  bool TriggerStoppedTimerForTest() WARN_UNUSED_RESULT;
  bool TriggerOngoingTimerForTest() WARN_UNUSED_RESULT;

 protected:
  BaseActivityLogger(const std::string& activity_name,
                     base::TimeDelta stopped_delay,
                     base::TimeDelta ongoing_interval);
  BaseActivityLogger(const BaseActivityLogger&) = delete;
  BaseActivityLogger& operator=(const BaseActivityLogger&) = delete;

  virtual ~BaseActivityLogger();

  // Returns a string of the format "0.5 sec ago" describing how long ago
  // |timestamp| occurred (compared to |clock_|'s idea of "now").
  std::string GetDelaySuffix(base::TimeTicks timestamp) const;

  // Callback used to log messages.
  LogCallback log_callback_;

  const std::unique_ptr<Clock> clock_;

  // String describing the type of activity being tracked.
  const std::string activity_name_;

  // Delay after the cessation of activity before logging that it's stopped.
  const base::TimeDelta stopped_delay_;

  // Interval for logging activity periodically.
  base::TimeDelta ongoing_interval_;

  // Used to log the cessation of activity and ongoing activity, respectively.
  base::OneShotTimer stopped_timer_;
  base::RepeatingTimer ongoing_timer_;
};

// PeriodicActivityLogger should be used for activity that is reported to powerd
// periodically, e.g. user or video activity (each reported every five seconds
// by Chrome while ongoing).
//
// It allows setting a "stopped delay" describing how long after the last report
// activity should be considered active (typically slightly longer than the
// interval with which reports are received) and an "ongoing interval" to log
// periodic messages while activity remains active.
//
// For example, with 5-second reporting interval, a stopped delay of 7 seconds,
// and an ongoing interval of 22 seconds:
//
// :00 reported -> "activity reported"
// :05 reported
// :10 reported
// :15 reported
// :20 reported
// :22          -> "activity ongoing; last reported 2 sec ago"
// :25 reported
// :32          -> "activity stopped; last reported 7 sec ago"
// :40 reported -> "activity reported"
class PeriodicActivityLogger : public BaseActivityLogger {
 public:
  // |activity_name| appears at the beginning of messages and describes the
  // activity, e.g. "User activity" or "Hovering".
  //
  // |stopped_delay| contains the duration after a report for which activity
  // will be considered ongoing. It should be longer than the interval between
  // reports.
  //
  // If |ongoing_interval| is nonzero, a message will be logged periodically
  // while activity is considered to be ongoing. If provided, it must be greater
  // than |stopped_delay|.
  PeriodicActivityLogger(const std::string& activity_name,
                         base::TimeDelta stopped_delay,
                         base::TimeDelta ongoing_interval);
  PeriodicActivityLogger(const PeriodicActivityLogger&) = delete;
  PeriodicActivityLogger& operator=(const PeriodicActivityLogger&) = delete;

  ~PeriodicActivityLogger() override;

  // Should be called when a periodic report of activity is received.
  void OnActivityReported();

 private:
  void LogStopped();
  void LogOngoing();

  // The time at which activity was last reported. Zero if activity hasn't yet
  // been reported.
  base::TimeTicks last_report_time_;
};

// StartStopActivityLogger should be used for activity that is reported to
// powerd via separate "start" and "stop" events, e.g. audio activity (reported
// by CRAS as changes to the number of active audio streams).
//
// It allows setting a "stopped delay" to suppress excess logging for activity
// that frequently starts and stops and an "ongoing interval" to log periodic
// messages while activity remains active.
//
// For example, with a stopped delay of 5 seconds and an ongoing interval of 10
// seconds:
//
// :00 started -> "activity started"
// :07 stopped
// :10 started
// :20         -> "activity ongoing"
// :30         -> "activity ongoing"
// :35 stopped
// :40         -> "activity stopped 5 sec ago"
// :42 started -> "activity started"
class StartStopActivityLogger : public BaseActivityLogger {
 public:
  // |activity_name| appears at the beginning of messages and describes the
  // activity, e.g. "User activity" or "Hovering".
  //
  // If |stopped_delay| is nonzero, it contains a duration after activity stops
  // during which future state changes will not be logged. If zero, all state
  // changes will be logged.
  //
  // If |ongoing_interval| is nonzero, a message will be logged periodically
  // while activity is considered to be ongoing.
  StartStopActivityLogger(const std::string& activity_name,
                          base::TimeDelta stopped_delay,
                          base::TimeDelta ongoing_interval);
  StartStopActivityLogger(const StartStopActivityLogger&) = delete;
  StartStopActivityLogger& operator=(const StartStopActivityLogger&) = delete;

  ~StartStopActivityLogger() override;

  // Should be called when activity starts or stops.
  void OnActivityStarted();
  void OnActivityStopped();

 private:
  void LogStopped();
  void LogOngoing();

  // The time at which activity last stopped. Zero if activity is currently
  // active or never started.
  base::TimeTicks stopped_time_;
};

// OngoingStateActivityLogger periodically logs a caller-provided state.
// The state is logged verbatim and can be changed.
//
// For example, with an ongoing interval of 10 seconds:
//
// :00 state "a"
// :10           -> "a"
// :20           -> "a"
// :26 state "b"
// :30           -> "b"
// :33 state ""
// :45 state "c"
// :55           -> "c"
class OngoingStateActivityLogger : public BaseActivityLogger {
 public:
  // |ongoing_interval| contains the interval between log messages while
  // |state_| is non-empty.
  explicit OngoingStateActivityLogger(base::TimeDelta ongoing_interval);
  OngoingStateActivityLogger(const OngoingStateActivityLogger&) = delete;
  OngoingStateActivityLogger& operator=(const OngoingStateActivityLogger&) =
      delete;

  ~OngoingStateActivityLogger() override;

  // Should be called when the state to log has changed.
  // When |state| transitions from empty to non-empty, a message will be logged
  // after |ongoing_interval| and then every |ongoing_interval|.
  // An empty string stops logging.
  void OnStateChanged(const std::string& state);

 private:
  void LogOngoing();

  // Current state message to log.
  std::string state_;
};

}  // namespace power_manager

#endif  // POWER_MANAGER_COMMON_ACTIVITY_LOGGER_H_
