// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "mpact/sim/generic/fifo.h"

#include <string>
#include <vector>

#include "absl/strings/string_view.h"

namespace mpact {
namespace sim {
namespace generic {

FifoBase::FifoBase(class ArchState *arch_state, absl::string_view name,
                   const std::vector<int> &shape, int element_size,
                   int default_capacity)
    : StateItemBase(arch_state, name, shape, element_size),
      Component(std::string(name), arch_state),
      depth_("depth", default_capacity),
      overflow_program_error_(nullptr),
      underflow_program_error_(nullptr),
      name_(name),
      capacity_(default_capacity),
      reserved_(0) {
  // empty
}

FifoBase::~FifoBase() {
  for (auto ptr : fifo_) {
    ptr->DecRef();
  }
  fifo_.clear();
}

bool FifoBase::IsFull() const { return fifo_.size() + reserved_ >= capacity_; }

bool FifoBase::IsEmpty() const { return fifo_.empty() && (reserved_ == 0); }

bool FifoBase::IsOverSubscribed() const {
  return fifo_.size() + reserved_ > capacity_;
}

void FifoBase::Reserve(int count) { reserved_ += count; }

bool FifoBase::Push(DataBuffer *db) {
  // If any slots are reserved, decrement first before checking for full.
  if (reserved_ > 0) {
    reserved_--;
  }
  if (IsFull()) {
    if (nullptr != overflow_program_error_) {
      overflow_program_error_->Raise("Overflow in fifo " + name_);
    }
    return false;
  } else {
    db->IncRef();
    fifo_.push_back(db);
    return true;
  }
}

void FifoBase::Pop() {
  if (fifo_.empty()) {
    if (nullptr != underflow_program_error_) {
      underflow_program_error_->Raise("Underflow in fifo " + name_);
    }
    return;
  }
  fifo_.front()->DecRef();
  fifo_.pop_front();
}

DataBuffer *FifoBase::Front() const {
  if (fifo_.empty()) {
    if (nullptr != underflow_program_error_) {
      underflow_program_error_->Raise("Underflow in fifo " + name_);
    }
    return nullptr;
  } else {
    return fifo_.front();
  }
}

unsigned FifoBase::Available() const { return fifo_.size(); }

void FifoBase::SetDataBuffer(DataBuffer *db) { Push(db); }

absl::Status FifoBase::ImportSelf(
    const mpact::sim::proto::ComponentData &component_data) {
  auto status = Component::ImportSelf(component_data);
  if (!status.ok()) return status;
  capacity_ = depth_.GetValue();
  return absl::OkStatus();
}

}  // namespace generic
}  // namespace sim
}  // namespace mpact
