/*
 *  Copyright (c) 2018 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 "api/video/video_bitrate_allocation.h"

#include <limits>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/stringutils.h"

namespace webrtc {

VideoBitrateAllocation::VideoBitrateAllocation() : sum_(0) {}

bool VideoBitrateAllocation::SetBitrate(size_t spatial_index,
                                        size_t temporal_index,
                                        uint32_t bitrate_bps) {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
  int64_t new_bitrate_sum_bps = sum_;
  rtc::Optional<uint32_t>& layer_bitrate =
      bitrates_[spatial_index][temporal_index];
  if (layer_bitrate) {
    RTC_DCHECK_LE(*layer_bitrate, sum_);
    new_bitrate_sum_bps -= *layer_bitrate;
  }
  new_bitrate_sum_bps += bitrate_bps;
  if (new_bitrate_sum_bps > kMaxBitrateBps)
    return false;

  layer_bitrate = bitrate_bps;
  sum_ = rtc::dchecked_cast<uint32_t>(new_bitrate_sum_bps);
  return true;
}

bool VideoBitrateAllocation::HasBitrate(size_t spatial_index,
                                        size_t temporal_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
  return bitrates_[spatial_index][temporal_index].has_value();
}

uint32_t VideoBitrateAllocation::GetBitrate(size_t spatial_index,
                                            size_t temporal_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
  return bitrates_[spatial_index][temporal_index].value_or(0);
}

// Whether the specific spatial layers has the bitrate set in any of its
// temporal layers.
bool VideoBitrateAllocation::IsSpatialLayerUsed(size_t spatial_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  for (size_t i = 0; i < kMaxTemporalStreams; ++i) {
    if (bitrates_[spatial_index][i].has_value())
      return true;
  }
  return false;
}

// Get the sum of all the temporal layer for a specific spatial layer.
uint32_t VideoBitrateAllocation::GetSpatialLayerSum(
    size_t spatial_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  return GetTemporalLayerSum(spatial_index, kMaxTemporalStreams - 1);
}

uint32_t VideoBitrateAllocation::GetTemporalLayerSum(
    size_t spatial_index,
    size_t temporal_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
  uint32_t sum = 0;
  for (size_t i = 0; i <= temporal_index; ++i) {
    sum += bitrates_[spatial_index][i].value_or(0);
  }
  return sum;
}

std::vector<uint32_t> VideoBitrateAllocation::GetTemporalLayerAllocation(
    size_t spatial_index) const {
  RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
  std::vector<uint32_t> temporal_rates;

  // Find the highest temporal layer with a defined bitrate in order to
  // determine the size of the temporal layer allocation.
  for (size_t i = kMaxTemporalStreams; i > 0; --i) {
    if (bitrates_[spatial_index][i - 1].has_value()) {
      temporal_rates.resize(i);
      break;
    }
  }

  for (size_t i = 0; i < temporal_rates.size(); ++i) {
    temporal_rates[i] = bitrates_[spatial_index][i].value_or(0);
  }

  return temporal_rates;
}

bool VideoBitrateAllocation::operator==(
    const VideoBitrateAllocation& other) const {
  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
      if (bitrates_[si][ti] != other.bitrates_[si][ti])
        return false;
    }
  }
  return true;
}

std::string VideoBitrateAllocation::ToString() const {
  if (sum_ == 0)
    return "VideoBitrateAllocation [ [] ]";

  // Max string length in practice is 260, but let's have some overhead and
  // round up to nearest power of two.
  char string_buf[512];
  rtc::SimpleStringBuilder ssb(string_buf);

  ssb << "VideoBitrateAllocation [";
  uint32_t spatial_cumulator = 0;
  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    RTC_DCHECK_LE(spatial_cumulator, sum_);
    if (spatial_cumulator == sum_)
      break;

    const uint32_t layer_sum = GetSpatialLayerSum(si);
    if (layer_sum == sum_) {
      ssb << " [";
    } else {
      if (si > 0)
        ssb << ",";
      ssb << '\n' << "  [";
    }
    spatial_cumulator += layer_sum;

    uint32_t temporal_cumulator = 0;
    for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
      RTC_DCHECK_LE(temporal_cumulator, layer_sum);
      if (temporal_cumulator == layer_sum)
        break;

      if (ti > 0)
        ssb << ", ";

      uint32_t bitrate = bitrates_[si][ti].value_or(0);
      ssb << bitrate;
      temporal_cumulator += bitrate;
    }
    ssb << "]";
  }

  RTC_DCHECK_EQ(spatial_cumulator, sum_);
  ssb << " ]";
  return ssb.str();
}

}  // namespace webrtc
