/*
 *  Copyright (c) 2019 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 "modules/video_coding/utility/decoded_frames_history.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <optional>

#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace video_coding {

DecodedFramesHistory::DecodedFramesHistory(size_t window_size)
    : buffer_(window_size) {}

DecodedFramesHistory::~DecodedFramesHistory() = default;

void DecodedFramesHistory::InsertDecoded(int64_t frame_id, uint32_t timestamp) {
  last_decoded_frame_ = frame_id;
  last_decoded_frame_timestamp_ = timestamp;
  int new_index = FrameIdToIndex(frame_id);

  RTC_DCHECK(last_frame_id_ < frame_id);

  // Clears expired values from the cyclic buffer_.
  if (last_frame_id_) {
    int64_t id_jump = frame_id - *last_frame_id_;
    int last_index = FrameIdToIndex(*last_frame_id_);

    if (id_jump >= static_cast<int64_t>(buffer_.size())) {
      std::fill(buffer_.begin(), buffer_.end(), false);
    } else if (new_index > last_index) {
      std::fill(buffer_.begin() + last_index + 1, buffer_.begin() + new_index,
                false);
    } else {
      std::fill(buffer_.begin() + last_index + 1, buffer_.end(), false);
      std::fill(buffer_.begin(), buffer_.begin() + new_index, false);
    }
  }

  buffer_[new_index] = true;
  last_frame_id_ = frame_id;
}

bool DecodedFramesHistory::WasDecoded(int64_t frame_id) const {
  if (!last_frame_id_)
    return false;

  // Reference to the picture_id out of the stored should happen.
  if (frame_id <= *last_frame_id_ - static_cast<int64_t>(buffer_.size())) {
    RTC_LOG(LS_WARNING) << "Referencing a frame out of the window. "
                           "Assuming it was undecoded to avoid artifacts.";
    return false;
  }

  if (frame_id > last_frame_id_)
    return false;

  return buffer_[FrameIdToIndex(frame_id)];
}

void DecodedFramesHistory::Clear() {
  last_decoded_frame_timestamp_.reset();
  last_decoded_frame_.reset();
  std::fill(buffer_.begin(), buffer_.end(), false);
  last_frame_id_.reset();
}

std::optional<int64_t> DecodedFramesHistory::GetLastDecodedFrameId() const {
  return last_decoded_frame_;
}

std::optional<uint32_t> DecodedFramesHistory::GetLastDecodedFrameTimestamp()
    const {
  return last_decoded_frame_timestamp_;
}

int DecodedFramesHistory::FrameIdToIndex(int64_t frame_id) const {
  int m = frame_id % buffer_.size();
  return m >= 0 ? m : m + buffer_.size();
}

}  // namespace video_coding
}  // namespace webrtc
