/*
 *  Copyright (c) 2013 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 WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_

#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"

#include <algorithm>

#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"

namespace webrtc {

class CriticalSectionWrapper;

class StreamStatisticianImpl : public StreamStatistician {
 public:
  StreamStatisticianImpl(Clock* clock,
                         RtcpStatisticsCallback* rtcp_callback,
                         StreamDataCountersCallback* rtp_callback);
  virtual ~StreamStatisticianImpl() {}

  virtual bool GetStatistics(RtcpStatistics* statistics, bool reset) OVERRIDE;
  virtual void GetDataCounters(size_t* bytes_received,
                               uint32_t* packets_received) const OVERRIDE;
  virtual void GetReceiveStreamDataCounters(
      StreamDataCounters* data_counters) const OVERRIDE;
  virtual uint32_t BitrateReceived() const OVERRIDE;
  virtual void ResetStatistics() OVERRIDE;
  virtual bool IsRetransmitOfOldPacket(const RTPHeader& header,
                                       int min_rtt) const OVERRIDE;
  virtual bool IsPacketInOrder(uint16_t sequence_number) const OVERRIDE;

  void IncomingPacket(const RTPHeader& rtp_header,
                      size_t bytes,
                      bool retransmitted);
  void FecPacketReceived();
  void SetMaxReorderingThreshold(int max_reordering_threshold);
  void ProcessBitrate();
  virtual void LastReceiveTimeNtp(uint32_t* secs, uint32_t* frac) const;

 private:
  bool InOrderPacketInternal(uint16_t sequence_number) const;
  RtcpStatistics CalculateRtcpStatistics();
  void UpdateJitter(const RTPHeader& header,
                    uint32_t receive_time_secs,
                    uint32_t receive_time_frac);
  void UpdateCounters(const RTPHeader& rtp_header,
                      size_t bytes,
                      bool retransmitted);
  void NotifyRtpCallback() LOCKS_EXCLUDED(stream_lock_.get());
  void NotifyRtcpCallback() LOCKS_EXCLUDED(stream_lock_.get());

  Clock* clock_;
  scoped_ptr<CriticalSectionWrapper> stream_lock_;
  Bitrate incoming_bitrate_;
  uint32_t ssrc_;
  int max_reordering_threshold_;  // In number of packets or sequence numbers.

  // Stats on received RTP packets.
  uint32_t jitter_q4_;
  uint32_t cumulative_loss_;
  uint32_t jitter_q4_transmission_time_offset_;

  int64_t last_receive_time_ms_;
  uint32_t last_receive_time_secs_;
  uint32_t last_receive_time_frac_;
  uint32_t last_received_timestamp_;
  int32_t last_received_transmission_time_offset_;
  uint16_t received_seq_first_;
  uint16_t received_seq_max_;
  uint16_t received_seq_wraps_;

  // Current counter values.
  size_t received_packet_overhead_;
  StreamDataCounters receive_counters_;

  // Stored counter values. Includes sum of reset counter values for the stream.
  StreamDataCounters stored_sum_receive_counters_;

  // Counter values when we sent the last report.
  uint32_t last_report_inorder_packets_;
  uint32_t last_report_old_packets_;
  uint16_t last_report_seq_max_;
  RtcpStatistics last_reported_statistics_;

  RtcpStatisticsCallback* const rtcp_callback_;
  StreamDataCountersCallback* const rtp_callback_;
};

class ReceiveStatisticsImpl : public ReceiveStatistics,
                              public RtcpStatisticsCallback,
                              public StreamDataCountersCallback {
 public:
  explicit ReceiveStatisticsImpl(Clock* clock);

  ~ReceiveStatisticsImpl();

  // Implement ReceiveStatistics.
  virtual void IncomingPacket(const RTPHeader& header,
                              size_t bytes,
                              bool retransmitted) OVERRIDE;
  virtual void FecPacketReceived(uint32_t ssrc) OVERRIDE;
  virtual StatisticianMap GetActiveStatisticians() const OVERRIDE;
  virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE;
  virtual void SetMaxReorderingThreshold(int max_reordering_threshold) OVERRIDE;

  // Implement Module.
  virtual int32_t Process() OVERRIDE;
  virtual int32_t TimeUntilNextProcess() OVERRIDE;

  virtual void RegisterRtcpStatisticsCallback(RtcpStatisticsCallback* callback)
      OVERRIDE;

  virtual void RegisterRtpStatisticsCallback(
      StreamDataCountersCallback* callback) OVERRIDE;

 private:
  virtual void StatisticsUpdated(const RtcpStatistics& statistics,
                                 uint32_t ssrc) OVERRIDE;
  virtual void DataCountersUpdated(const StreamDataCounters& counters,
                                   uint32_t ssrc) OVERRIDE;

  typedef std::map<uint32_t, StreamStatisticianImpl*> StatisticianImplMap;

  Clock* clock_;
  scoped_ptr<CriticalSectionWrapper> receive_statistics_lock_;
  int64_t last_rate_update_ms_;
  StatisticianImplMap statisticians_;

  RtcpStatisticsCallback* rtcp_stats_callback_;
  StreamDataCountersCallback* rtp_stats_callback_;
};
}  // namespace webrtc
#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
