/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef VIDEO_CALL_STATS_H_
#define VIDEO_CALL_STATS_H_

#include <list>
#include <memory>

#include "api/sequence_checker.h"
#include "modules/include/module.h"
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/synchronization/mutex.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

// CallStats keeps track of statistics for a call.
// TODO(webrtc:11489): Make call_stats_ not depend on ProcessThread and
// make callbacks on the worker thread (TQ).
class CallStats : public Module, public RtcpRttStats {
 public:
  // Time interval for updating the observers.
  static constexpr int64_t kUpdateIntervalMs = 1000;

  CallStats(Clock* clock, ProcessThread* process_thread);
  ~CallStats() override;

  CallStats(const CallStats&) = delete;
  CallStats& operator=(const CallStats&) = delete;

  // Registers/deregisters a new observer to receive statistics updates.
  // Must be called from the construction thread.
  void RegisterStatsObserver(CallStatsObserver* observer);
  void DeregisterStatsObserver(CallStatsObserver* observer);

  // Expose `LastProcessedRtt()` from RtcpRttStats to the public interface, as
  // it is the part of the API that is needed by direct users of CallStats.
  // TODO(tommi): Threading or lifetime guarantees are not explicit in how
  // CallStats is used as RtcpRttStats or how pointers are cached in a
  // few different places (distributed via Call). It would be good to clarify
  // from what thread/TQ calls to OnRttUpdate and LastProcessedRtt need to be
  // allowed.
  int64_t LastProcessedRtt() const override;

  // Exposed for tests to test histogram support.
  void UpdateHistogramsForTest() { UpdateHistograms(); }

  // Helper struct keeping track of the time a rtt value is reported.
  struct RttTime {
    RttTime(int64_t new_rtt, int64_t rtt_time) : rtt(new_rtt), time(rtt_time) {}
    const int64_t rtt;
    const int64_t time;
  };

 private:
  // RtcpRttStats implementation.
  void OnRttUpdate(int64_t rtt) override;

  // Implements Module, to use the process thread.
  int64_t TimeUntilNextProcess() override;
  void Process() override;

  // TODO(tommi): Use this to know when we're attached to the process thread?
  // Alternatively, inject that pointer via the ctor since the call_stats
  // test code, isn't using a processthread atm.
  void ProcessThreadAttached(ProcessThread* process_thread) override;

  // This method must only be called when the process thread is not
  // running, and from the construction thread.
  void UpdateHistograms();

  Clock* const clock_;

  // The last time 'Process' resulted in statistic update.
  int64_t last_process_time_ RTC_GUARDED_BY(process_thread_checker_);
  // The last RTT in the statistics update (zero if there is no valid estimate).
  int64_t max_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);

  // Accessed from random threads (seemingly). Consider atomic.
  // `avg_rtt_ms_` is allowed to be read on the process thread without a lock.
  // `avg_rtt_ms_lock_` must be held elsewhere for reading.
  // `avg_rtt_ms_lock_` must be held on the process thread for writing.
  int64_t avg_rtt_ms_;

  // Protects `avg_rtt_ms_`.
  mutable Mutex avg_rtt_ms_lock_;

  // `sum_avg_rtt_ms_`, `num_avg_rtt_` and `time_of_first_rtt_ms_` are only used
  // on the ProcessThread when running. When the Process Thread is not running,
  // (and only then) they can be used in UpdateHistograms(), usually called from
  // the dtor.
  int64_t sum_avg_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);
  int64_t num_avg_rtt_ RTC_GUARDED_BY(process_thread_checker_);
  int64_t time_of_first_rtt_ms_ RTC_GUARDED_BY(process_thread_checker_);

  // All Rtt reports within valid time interval, oldest first.
  std::list<RttTime> reports_ RTC_GUARDED_BY(process_thread_checker_);

  // Observers getting stats reports.
  // When attached to ProcessThread, this is read-only. In order to allow
  // modification, we detach from the process thread while the observer
  // list is updated, to avoid races. This allows us to not require a lock
  // for the observers_ list, which makes the most common case lock free.
  std::list<CallStatsObserver*> observers_;

  SequenceChecker construction_thread_checker_;
  SequenceChecker process_thread_checker_;
  ProcessThread* const process_thread_;
  bool process_thread_running_ RTC_GUARDED_BY(construction_thread_checker_);
};

}  // namespace webrtc

#endif  // VIDEO_CALL_STATS_H_
