/*
 *  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 "modules/include/module.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/thread_checker.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

class CallStatsObserver;

// CallStats keeps track of statistics for a call.
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();

  // 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_|.
  rtc::CriticalSection 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_;

  rtc::ThreadChecker construction_thread_checker_;
  rtc::ThreadChecker process_thread_checker_;
  ProcessThread* const process_thread_;
  bool process_thread_running_ RTC_GUARDED_BY(construction_thread_checker_);

  RTC_DISALLOW_COPY_AND_ASSIGN(CallStats);
};

}  // namespace webrtc

#endif  // VIDEO_CALL_STATS_H_
