/*
 *  Copyright (c) 2016 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.
 */

#include "webrtc/video/send_delay_stats.h"

#include <utility>

#include "webrtc/base/logging.h"
#include "webrtc/system_wrappers/include/metrics.h"

namespace webrtc {
namespace {
// Packet with a larger delay are removed and excluded from the delay stats.
// Set to larger than max histogram delay which is 10000.
const int64_t kMaxSentPacketDelayMs = 11000;
const size_t kMaxPacketMapSize = 2000;

// Limit for the maximum number of streams to calculate stats for.
const size_t kMaxSsrcMapSize = 50;
const int kMinRequiredPeriodicSamples = 5;
}  // namespace

SendDelayStats::SendDelayStats(Clock* clock)
    : clock_(clock), num_old_packets_(0), num_skipped_packets_(0) {}

SendDelayStats::~SendDelayStats() {
  if (num_old_packets_ > 0 || num_skipped_packets_ > 0) {
    LOG(LS_WARNING) << "Delay stats: number of old packets " << num_old_packets_
                    << ", skipped packets " << num_skipped_packets_
                    << ". Number of streams " << send_delay_counters_.size();
  }
  UpdateHistograms();
}

void SendDelayStats::UpdateHistograms() {
  rtc::CritScope lock(&crit_);
  for (const auto& it : send_delay_counters_) {
    AggregatedStats stats = it.second->GetStats();
    if (stats.num_samples >= kMinRequiredPeriodicSamples) {
      RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SendDelayInMs", stats.average);
    }
  }
}

void SendDelayStats::AddSsrcs(const VideoSendStream::Config& config) {
  rtc::CritScope lock(&crit_);
  if (ssrcs_.size() > kMaxSsrcMapSize)
    return;
  for (const auto& ssrc : config.rtp.ssrcs)
    ssrcs_.insert(ssrc);
}

AvgCounter* SendDelayStats::GetSendDelayCounter(uint32_t ssrc) {
  const auto& it = send_delay_counters_.find(ssrc);
  if (it != send_delay_counters_.end())
    return it->second.get();

  AvgCounter* counter = new AvgCounter(clock_, nullptr, false);
  send_delay_counters_[ssrc].reset(counter);
  return counter;
}

void SendDelayStats::OnSendPacket(uint16_t packet_id,
                                  int64_t capture_time_ms,
                                  uint32_t ssrc) {
  // Packet sent to transport.
  rtc::CritScope lock(&crit_);
  if (ssrcs_.find(ssrc) == ssrcs_.end())
    return;

  int64_t now = clock_->TimeInMilliseconds();
  RemoveOld(now, &packets_);

  if (packets_.size() > kMaxPacketMapSize) {
    ++num_skipped_packets_;
    return;
  }
  packets_.insert(
      std::make_pair(packet_id, Packet(ssrc, capture_time_ms, now)));
}

bool SendDelayStats::OnSentPacket(int packet_id, int64_t time_ms) {
  // Packet leaving socket.
  if (packet_id == -1)
    return false;

  rtc::CritScope lock(&crit_);
  auto it = packets_.find(packet_id);
  if (it == packets_.end())
    return false;

  // TODO(asapersson): Remove SendSideDelayUpdated(), use capture -> sent.
  // Elapsed time from send (to transport) -> sent (leaving socket).
  int diff_ms = time_ms - it->second.send_time_ms;
  GetSendDelayCounter(it->second.ssrc)->Add(diff_ms);
  packets_.erase(it);
  return true;
}

void SendDelayStats::RemoveOld(int64_t now, PacketMap* packets) {
  while (!packets->empty()) {
    auto it = packets->begin();
    if (now - it->second.capture_time_ms < kMaxSentPacketDelayMs)
      break;

    packets->erase(it);
    ++num_old_packets_;
  }
}

}  // namespace webrtc
