/*
 *  Copyright (c) 2014 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 "video/report_block_stats.h"

namespace webrtc {

namespace {
int FractionLost(uint32_t num_lost_sequence_numbers,
                 uint32_t num_sequence_numbers) {
  if (num_sequence_numbers == 0) {
    return 0;
  }
  return ((num_lost_sequence_numbers * 255) + (num_sequence_numbers / 2)) /
      num_sequence_numbers;
}
}  // namespace


// Helper class for rtcp statistics.
ReportBlockStats::ReportBlockStats()
    : num_sequence_numbers_(0),
      num_lost_sequence_numbers_(0) {
}

void ReportBlockStats::Store(const RtcpStatistics& rtcp_stats,
                             uint32_t remote_ssrc,
                             uint32_t source_ssrc) {
  RTCPReportBlock block;
  block.packets_lost = rtcp_stats.packets_lost;
  block.fraction_lost = rtcp_stats.fraction_lost;
  block.extended_highest_sequence_number =
      rtcp_stats.extended_highest_sequence_number;
  block.jitter = rtcp_stats.jitter;
  block.sender_ssrc = remote_ssrc;
  block.source_ssrc = source_ssrc;
  uint32_t num_sequence_numbers = 0;
  uint32_t num_lost_sequence_numbers = 0;
  StoreAndAddPacketIncrement(
      block, &num_sequence_numbers, &num_lost_sequence_numbers);
}

RTCPReportBlock ReportBlockStats::AggregateAndStore(
    const ReportBlockVector& report_blocks) {
  RTCPReportBlock aggregate;
  if (report_blocks.empty()) {
    return aggregate;
  }
  uint32_t num_sequence_numbers = 0;
  uint32_t num_lost_sequence_numbers = 0;
  ReportBlockVector::const_iterator report_block = report_blocks.begin();
  for (; report_block != report_blocks.end(); ++report_block) {
    aggregate.packets_lost += report_block->packets_lost;
    aggregate.jitter += report_block->jitter;
    StoreAndAddPacketIncrement(*report_block,
                               &num_sequence_numbers,
                               &num_lost_sequence_numbers);
  }

  if (report_blocks.size() == 1) {
    // No aggregation needed.
    return report_blocks[0];
  }
  // Fraction lost since previous report block.
  aggregate.fraction_lost =
      FractionLost(num_lost_sequence_numbers, num_sequence_numbers);
  aggregate.jitter = static_cast<uint32_t>(
      (aggregate.jitter + report_blocks.size() / 2) / report_blocks.size());
  return aggregate;
}

void ReportBlockStats::StoreAndAddPacketIncrement(
    const RTCPReportBlock& report_block,
    uint32_t* num_sequence_numbers,
    uint32_t* num_lost_sequence_numbers) {
  // Get diff with previous report block.
  ReportBlockMap::iterator prev_report_block =
      prev_report_blocks_.find(report_block.source_ssrc);
  if (prev_report_block != prev_report_blocks_.end()) {
    int seq_num_diff =
        report_block.extended_highest_sequence_number -
        prev_report_block->second.extended_highest_sequence_number;
    int cum_loss_diff =
        report_block.packets_lost - prev_report_block->second.packets_lost;
    if (seq_num_diff >= 0 && cum_loss_diff >= 0) {
      *num_sequence_numbers += seq_num_diff;
      *num_lost_sequence_numbers += cum_loss_diff;
      // Update total number of packets/lost packets.
      num_sequence_numbers_ += seq_num_diff;
      num_lost_sequence_numbers_ += cum_loss_diff;
    }
  }
  // Store current report block.
  prev_report_blocks_[report_block.source_ssrc] = report_block;
}

int ReportBlockStats::FractionLostInPercent() const {
  if (num_sequence_numbers_ == 0) {
    return -1;
  }
  return FractionLost(
      num_lost_sequence_numbers_, num_sequence_numbers_) * 100 / 255;
}

}  // namespace webrtc

