/*
 * Copyright (c) 2022, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#ifndef AOM_AV1_REFERENCE_MANAGER_H_
#define AOM_AV1_REFERENCE_MANAGER_H_

#include <deque>
#include <iostream>
#include <vector>

#include "av1/ratectrl_qmode_interface.h"

namespace aom {

enum class RefUpdateType { kForward, kBackward, kLast, kNone };

class RefFrameManager {
 public:
  explicit RefFrameManager(int ref_frame_table_size, int max_ref_frames)
      : ref_frame_table_(ref_frame_table_size),
        max_ref_frames_(max_ref_frames) {
    // forward_max_size_ define max number of arf frames that can exists at
    // the same time. In the other words, it's the max size of forward_stack_.
    // TODO(angiebird): Figure out if this number is optimal.
    forward_max_size_ = ref_frame_table_size - 2;
    cur_global_order_idx_ = 0;
    Reset();
  }
  ~RefFrameManager() = default;

  RefFrameManager(const RefFrameManager &) = delete;
  RefFrameManager &operator=(const RefFrameManager &) = delete;

  friend std::ostream &operator<<(std::ostream &os,
                                  const RefFrameManager &rfm) {
    os << "=" << std::endl;
    os << "forward: ";
    for (const auto &ref_idx : rfm.forward_stack_) {
      os << rfm.ref_frame_table_[ref_idx].order_idx << " ";
    }
    os << std::endl;
    os << "backward: ";
    for (const auto &ref_idx : rfm.backward_queue_) {
      os << rfm.ref_frame_table_[ref_idx].order_idx << " ";
    }
    os << std::endl;
    os << "last: ";
    for (const auto &ref_idx : rfm.last_queue_) {
      os << rfm.ref_frame_table_[ref_idx].order_idx << " ";
    }
    os << std::endl;
    return os;
  }

  void Reset();
  int AllocateRefIdx();
  int GetRefFrameCountByType(RefUpdateType ref_update_type) const;
  int GetRefFrameCount() const;
  std::vector<ReferenceFrame> GetRefFrameListByPriority() const;
  int GetRefFrameIdxByPriority(RefUpdateType ref_update_type,
                               int priority_idx) const;
  GopFrame GetRefFrameByPriority(RefUpdateType ref_update_type,
                                 int priority_idx) const;
  GopFrame GetRefFrameByIndex(int ref_idx) const;
  void UpdateOrder(int global_order_idx);
  int ColocatedRefIdx(int global_order_idx);
  int ForwardMaxSize() const { return forward_max_size_; }
  int MaxRefFrame() const { return max_ref_frames_; }
  int CurGlobalOrderIdx() const { return cur_global_order_idx_; }
  void UpdateRefFrameTable(GopFrame *gop_frame);
  ReferenceFrame GetPrimaryRefFrame(const GopFrame &gop_frame) const;

 private:
  int forward_max_size_;
  int cur_global_order_idx_;
  RefFrameTable ref_frame_table_;
  int max_ref_frames_;
  bool allow_two_fwd_frames_;
  std::deque<int> free_ref_idx_list_;
  std::vector<int> forward_stack_;
  std::deque<int> backward_queue_;
  std::deque<int> last_queue_;
};

}  // namespace aom

#endif  // AOM_AV1_REFERENCE_MANAGER_H_
