// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/blink/buffered_data_source_host_impl.h"

#include "media/base/timestamp_constants.h"

namespace media {

// We want a relatively small window for estimating bandwidth,
// that way we don't need to worry too much about seeks and pause
// throwing off the estimates.
constexpr base::TimeDelta kDownloadHistoryWindowSeconds =
    base::TimeDelta::FromSecondsD(10.0);

// Limit the number of entries in the rate estimator queue.
// 1024 entries should be more than enough.
constexpr size_t kDownloadHistoryMaxEntries = 1024;

// Just in case someone gives progress one byte at a time,
// let's aggregate progress updates together until we reach
// at least this many bytes.
constexpr int64_t kDownloadHistoryMinBytesPerEntry = 1000;

BufferedDataSourceHostImpl::BufferedDataSourceHostImpl(
    base::RepeatingClosure progress_cb,
    const base::TickClock* tick_clock)
    : total_bytes_(0),
      did_loading_progress_(false),
      progress_cb_(std::move(progress_cb)),
      tick_clock_(tick_clock) {}

BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() = default;

void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) {
  total_bytes_ = total_bytes;
}

int64_t BufferedDataSourceHostImpl::UnloadedBytesInInterval(
    const Interval<int64_t>& interval) const {
  int64_t bytes = 0;
  auto i = buffered_byte_ranges_.find(interval.begin);
  while (i != buffered_byte_ranges_.end()) {
    if (i.interval_begin() >= interval.end)
      break;
    if (!i.value()) {
      Interval<int64_t> intersection = i.interval().Intersect(interval);
      if (!intersection.Empty())
        bytes += intersection.end - intersection.begin;
    }
    ++i;
  }
  return bytes;
}

void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start,
                                                      int64_t end) {
  int64_t new_bytes = UnloadedBytesInInterval(Interval<int64_t>(start, end));
  if (new_bytes > 0)
    did_loading_progress_ = true;
  buffered_byte_ranges_.SetInterval(start, end, 1);

  base::TimeTicks now = tick_clock_->NowTicks();
  int64_t bytes_so_far = 0;
  if (!download_history_.empty())
    bytes_so_far = download_history_.back().second;
  bytes_so_far += new_bytes;

  // If the difference between the last entry and the second to last entry is
  // less than kDownloadHistoryMinBytesPerEntry, just overwrite the last entry.
  if (download_history_.size() > 1 &&
      download_history_.back().second - (download_history_.end() - 2)->second <
          kDownloadHistoryMinBytesPerEntry) {
    download_history_.back() = std::make_pair(now, bytes_so_far);
  } else {
    download_history_.emplace_back(now, bytes_so_far);
  }
  DCHECK_GE(download_history_.size(), 1u);
  // Drop entries that are too old.
  while (download_history_.size() > kDownloadHistoryMaxEntries ||
         download_history_.back().first - download_history_.front().first >
             kDownloadHistoryWindowSeconds) {
    download_history_.pop_front();
  }
  progress_cb_.Run();
}

static base::TimeDelta TimeForByteOffset(int64_t byte_offset,
                                         int64_t total_bytes,
                                         base::TimeDelta duration) {
  double position = static_cast<double>(byte_offset) / total_bytes;
  // Snap to the beginning/end where the approximation can look especially bad.
  if (position < 0.01)
    return base::TimeDelta();
  if (position > 0.99)
    return duration;
  return base::TimeDelta::FromMilliseconds(
      static_cast<int64_t>(position * duration.InMilliseconds()));
}

void BufferedDataSourceHostImpl::AddBufferedTimeRanges(
    Ranges<base::TimeDelta>* buffered_time_ranges,
    base::TimeDelta media_duration) const {
  DCHECK(media_duration != kNoTimestamp);
  DCHECK(media_duration != kInfiniteDuration);
  if (total_bytes_ && !buffered_byte_ranges_.empty()) {
    for (const auto i : buffered_byte_ranges_) {
      if (i.second) {
        int64_t start = i.first.begin;
        int64_t end = i.first.end;
        buffered_time_ranges->Add(
            TimeForByteOffset(start, total_bytes_, media_duration),
            TimeForByteOffset(end, total_bytes_, media_duration));
      }
    }
  }
}

bool BufferedDataSourceHostImpl::DidLoadingProgress() {
  bool ret = did_loading_progress_;
  did_loading_progress_ = false;
  return ret;
}

double BufferedDataSourceHostImpl::DownloadRate() const {
  // If the download history is really small, any estimate we make is going to
  // be wildly inaccurate, so let's not make any estimates until we have more
  // data.
  if (download_history_.size() < 5)
    return 0.0;

  // The data we get is bursty, so we get multiple measuring points very close
  // together. These bursts will often lead us to over-estimate the download
  // rate. By iterating over the beginning of the time series and picking the
  // data point that has the lowest download rate, we avoid over-estimating.
  const double kVeryLargeRate = 1.0E20;
  double download_rate = kVeryLargeRate;
  for (int i = 0; i < std::min<int>(20, download_history_.size() - 3); i++) {
    int64_t downloaded_bytes =
        download_history_.back().second - download_history_[i].second;
    base::TimeTicks now = tick_clock_->NowTicks();
    base::TimeDelta downloaded_seconds = now - download_history_[i].first;
    if (downloaded_seconds <= base::TimeDelta())
      continue;
    download_rate = std::min(
        download_rate, downloaded_bytes / downloaded_seconds.InSecondsF());
  }
  return download_rate == kVeryLargeRate ? 0.0 : download_rate;
}

bool BufferedDataSourceHostImpl::CanPlayThrough(
    base::TimeDelta current_position,
    base::TimeDelta media_duration,
    double playback_rate) const {
  DCHECK_GE(playback_rate, 0);
  if (!total_bytes_ || media_duration <= base::TimeDelta() ||
      media_duration == kInfiniteDuration) {
    return false;
  }
  if (current_position > media_duration)
    return true;
  double fraction = current_position.InSecondsF() / media_duration.InSecondsF();
  int64_t byte_pos = total_bytes_ * fraction;
  if (byte_pos < 0)
    byte_pos = 0;

  int64_t unloaded_bytes =
      UnloadedBytesInInterval(Interval<int64_t>(byte_pos, total_bytes_));

  if (unloaded_bytes == 0)
    return true;

  double download_rate = DownloadRate();
  if (download_rate <= 0.0)
    return false;

  return unloaded_bytes / download_rate <
         (media_duration - current_position).InSecondsF() / playback_rate;
}

void BufferedDataSourceHostImpl::SetTickClockForTest(
    const base::TickClock* tick_clock) {
  tick_clock_ = tick_clock;
}

}  // namespace media
