/*
 *  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 "webrtc/modules/pacing/bitrate_prober.h"

#include <assert.h>
#include <algorithm>
#include <limits>
#include <sstream>

#include "webrtc/modules/pacing/include/paced_sender.h"
#include "webrtc/system_wrappers/interface/logging.h"

namespace webrtc {

namespace {
int ComputeDeltaFromBitrate(size_t packet_size, int bitrate_bps) {
  assert(bitrate_bps > 0);
  // Compute the time delta needed to send packet_size bytes at bitrate_bps
  // bps. Result is in milliseconds.
  return static_cast<int>(1000ll * static_cast<int64_t>(packet_size) * 8ll /
      bitrate_bps);
}
}  // namespace

BitrateProber::BitrateProber()
    : probing_state_(kDisabled),
      packet_size_last_send_(0),
      time_last_send_ms_(-1) {
}

void BitrateProber::SetEnabled(bool enable) {
  if (enable) {
    if (probing_state_ == kDisabled) {
      probing_state_ = kAllowedToProbe;
      LOG(LS_INFO) << "Initial bandwidth probing enabled";
    }
  } else {
    probing_state_ = kDisabled;
    LOG(LS_INFO) << "Initial bandwidth probing disabled";
  }
}

bool BitrateProber::IsProbing() const {
  return probing_state_ == kProbing;
}

void BitrateProber::MaybeInitializeProbe(int bitrate_bps) {
  if (probing_state_ != kAllowedToProbe)
    return;
  probe_bitrates_.clear();
  // Max number of packets used for probing.
  const int kMaxNumProbes = 2;
  const int kPacketsPerProbe = 5;
  const float kProbeBitrateMultipliers[kMaxNumProbes] = {3, 6};
  int bitrates_bps[kMaxNumProbes];
  std::stringstream bitrate_log;
  bitrate_log << "Start probing for bandwidth, bitrates:";
  for (int i = 0; i < kMaxNumProbes; ++i) {
    bitrates_bps[i] = kProbeBitrateMultipliers[i] * bitrate_bps;
    bitrate_log << " " << bitrates_bps[i];
    // We need one extra to get 5 deltas for the first probe.
    if (i == 0)
      probe_bitrates_.push_back(bitrates_bps[i]);
    for (int j = 0; j < kPacketsPerProbe; ++j)
      probe_bitrates_.push_back(bitrates_bps[i]);
  }
  bitrate_log << ", num packets: " << probe_bitrates_.size();
  LOG(LS_INFO) << bitrate_log.str().c_str();
  probing_state_ = kProbing;
}

int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
  if (probing_state_ != kDisabled && probe_bitrates_.empty()) {
    probing_state_ = kWait;
  }
  if (probe_bitrates_.empty()) {
    // No probe started, or waiting for next probe.
    return -1;
  }
  int64_t elapsed_time_ms = now_ms - time_last_send_ms_;
  // We will send the first probe packet immediately if no packet has been
  // sent before.
  int time_until_probe_ms = 0;
  if (packet_size_last_send_ > PacedSender::kMinProbePacketSize &&
      probing_state_ == kProbing) {
    int next_delta_ms = ComputeDeltaFromBitrate(packet_size_last_send_,
                                                probe_bitrates_.front());
    time_until_probe_ms = next_delta_ms - elapsed_time_ms;
    // There is no point in trying to probe with less than 1 ms between packets
    // as it essentially means trying to probe at infinite bandwidth.
    const int kMinProbeDeltaMs = 1;
    // If we have waited more than 3 ms for a new packet to probe with we will
    // consider this probing session over.
    const int kMaxProbeDelayMs = 3;
    if (next_delta_ms < kMinProbeDeltaMs ||
        time_until_probe_ms < -kMaxProbeDelayMs) {
      // We currently disable probing after the first probe, as we only want
      // to probe at the beginning of a connection. We should set this to
      // kWait if we later want to probe periodically.
      probing_state_ = kWait;
      LOG(LS_INFO) << "Next delta too small, stop probing.";
      time_until_probe_ms = 0;
    }
  }
  return std::max(time_until_probe_ms, 0);
}

size_t BitrateProber::RecommendedPacketSize() const {
  return packet_size_last_send_;
}

void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) {
  assert(packet_size > 0);
  packet_size_last_send_ = packet_size;
  time_last_send_ms_ = now_ms;
  if (probing_state_ != kProbing)
    return;
  if (!probe_bitrates_.empty())
    probe_bitrates_.pop_front();
}
}  // namespace webrtc
