/*
 *  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 <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>

#include "api/video/video_codec_constants.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

VideoBitrateAllocation::VideoBitrateAllocation()
    : sum_(0), is_bw_limited_(false) {}

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_;
  std::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;
}

std::vector<std::optional<VideoBitrateAllocation>>
VideoBitrateAllocation::GetSimulcastAllocations() const {
  std::vector<std::optional<VideoBitrateAllocation>> bitrates;
  for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
    std::optional<VideoBitrateAllocation> layer_bitrate;
    if (IsSpatialLayerUsed(si)) {
      layer_bitrate = VideoBitrateAllocation();
      for (int tl = 0; tl < kMaxTemporalStreams; ++tl) {
        if (HasBitrate(si, tl))
          layer_bitrate->SetBitrate(0, tl, GetBitrate(si, tl));
      }
    }
    bitrates.push_back(layer_bitrate);
  }
  return bitrates;
}

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_ && si == 0) {
      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
