// 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.

#ifndef MPACT_SIM_GENERIC_FIFO_H_
#define MPACT_SIM_GENERIC_FIFO_H_

#include <any>
#include <cstdint>
#include <deque>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/component.h"
#include "mpact/sim/generic/config.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/program_error.h"
#include "mpact/sim/generic/state_item.h"
#include "mpact/sim/generic/state_item_base.h"

// Contains the basic generic definitions for classes used to model
// fifo state in simulated architectures. Fifos can contain scalar,
// one-dimensional vector, or two-dimensional array values.

namespace mpact {
namespace sim {
namespace generic {

class FifoBase;

template <typename T, typename Enable = void>
class FifoSourceOperand : public SourceOperandInterface {
 public:
  // Constructor. Note, default constructor deleted.
  explicit FifoSourceOperand(FifoBase* fifo);
  FifoSourceOperand(FifoBase* fifo, const std::string op_name);
  FifoSourceOperand() = delete;

  // These accessor methods are defined to satisfy the interface. However,
  // in many cases, the purpose of the fifo is only to hold the underlying
  // DataBuffer instance, until popped in its entirety. It is therefore
  // expected that these accessors will not be used much.
  // Accessor methods call into the fifo_ data_buffer to obtain the values.
  // The index is in one dimension. For scalar registers it should always be
  // zero, for vector registers it is the element index. For higher order
  // register shapes it should be the linearized row-major order index.
  bool AsBool(int i) override;
  int8_t AsInt8(int i) override;
  uint8_t AsUint8(int i) override;
  int16_t AsInt16(int i) override;
  uint16_t AsUint16(int i) override;
  int32_t AsInt32(int i) override;
  uint32_t AsUint32(int i) override;
  int64_t AsInt64(int i) override;
  uint64_t AsUint64(int i) override;

  // Returns the FifoBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(fifo_); }

  // Returns the shape of the fifo elements.
  std::vector<int> shape() const override;

  std::string AsString() const override { return op_name_; }

 private:
  FifoBase* fifo_;
  std::string op_name_;
};

// Fifo destination operand type with element value type T. It is agnostic
// of the actual structure of the underlying fifo element (scalar, vector,
// matrix).
template <typename T>
class FifoDestinationOperand : public DestinationOperandInterface {
 public:
  // Constructors
  FifoDestinationOperand(FifoBase* fifo, int latency, std::string op_name);
  FifoDestinationOperand(FifoBase* fifo, int latency);
  FifoDestinationOperand() = delete;

  // Initializes the DataBuffer instance so that when Submit is called, it can
  // be entered into the correct delay line, with the correct latency, targeting
  // the correct fifo.
  void InitializeDataBuffer(DataBuffer* db) override;

  // Since a fifo stores multiple values, this method will return a nullptr
  // as it does not make sense to copy the value from a fifo into a destination
  // DataBuffer instance that is destined for that fifo.
  DataBuffer* CopyDataBuffer() override { return nullptr; }

  // Allocates and returns an initialized DataBuffer instance.
  DataBuffer* AllocateDataBuffer() override;

  // Returns the FifoBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(fifo_); }

  // Returns the latency associated with writes to this fifo operand.
  int latency() const override { return latency_; }

  // Returns the shape of the underlying fifo element (the number of elements in
  // each dimension). For instance {0} indicates a scalar quantity, whereas
  // {128} indicates an 128 element vector quantity.
  std::vector<int> shape() const override;

  std::string AsString() const override { return op_name_; }

 private:
  FifoBase* fifo_;
  DataBufferFactory* db_factory_;
  int latency_;
  DataBufferDelayLine* delay_line_;
  std::string op_name_;
};

// Base class for fifo types. Implements DataBufferInterface that
// the base class StateItemBase does not.
// The Fifo class supports the ability to reserve slots in the fifo for future
// pushes of data. The reserved slots are counted for the purpose of determining
// IsFull() or IsEmpty(), but are not counted in the number of Available()
// elements. The use of the reservation capability is not required to push data,
// but is implemented to provide modeling support for architectures where the
// allocation of fifo slots are separated from the actual push of data.
// No default constructor - should only be constructed from the derived classes.
class FifoBase : public StateItemBase, public Component {
  // Only constructed from derived classes.
 protected:
  FifoBase(class ArchState* arch_state, absl::string_view name,
           const std::vector<int>& shape, int element_size,
           int default_capacity);
  FifoBase() = delete;
  FifoBase(const FifoBase&) = delete;

 public:
  ~FifoBase() override;

 public:
  // Pushes the DataBuffer to the fifo provided there is space available.
  void SetDataBuffer(DataBuffer* db) override;

  // Returns true if the count of reserved and full slots equals or exceeds
  // fifo capacity.
  virtual bool IsFull() const;

  // Returns true if the fifo is empty and has zero slots reserved.
  virtual bool IsEmpty() const;

  // Returns true if the sum of reserved and full slots exceeds fifo capacity.
  // The fifo will not accept pushes once full, so the overflow can only only
  // be true if there are reserved slots.
  virtual bool IsOverSubscribed() const;

  // Reserves count slots in the fifo for future pushes. There is no check on
  // whether this causes overflow. This allows for a Reserve to be performed in
  // "parallel" with a Pop() without causing an error. If needed, an overflow
  // check should be performed at the end of the simulated cycle.
  virtual void Reserve(int count);

  // Pushes a value into the fifo, returns true if successful. Reference count
  // of the DataBuffer is incremented as part of Push. If the reserved count
  // is greater than zero it will decrement the reserved count. If the push
  // would overflow the fifo it returns false, and raises the overflow program
  // error if set.
  virtual bool Push(DataBuffer* db);

  // Returns a pointer to the DataBuffer at the front of the fifo. If the fifo
  // is empty, the nullptr is returned and the underflow program error, if set,
  // is raised.
  DataBuffer* Front() const;

  // Removes the front element of the fifo and decrements its reference count.
  // If the fifo is empty, the underflow program error, if set, is raised.
  virtual void Pop();

  // Returns max depth of fifo.
  unsigned Capacity() const { return capacity_; }

  // Returns the number of elements currently held in the fifo.
  unsigned Available() const;

  // Returns the number of reserved slots.
  unsigned Reserved() const { return reserved_; }

  // Setters for ProgramErrors
  void SetOverflowProgramError(std::unique_ptr<ProgramError>* program_error) {
    overflow_program_error_ = std::move(*program_error);
  }

  void SetUnderflowProgramError(std::unique_ptr<ProgramError>* program_error) {
    underflow_program_error_ = std::move(*program_error);
  }

 protected:
  // Configuration import.
  absl::Status ImportSelf(
      const mpact::sim::proto::ComponentData& component_data) override;

  ProgramError* overflow_program_error() {
    return overflow_program_error_.get();
  }
  ProgramError* underflow_program_error() {
    return underflow_program_error_.get();
  }

 private:
  Config<uint64_t> depth_;
  std::unique_ptr<ProgramError> overflow_program_error_;
  std::unique_ptr<ProgramError> underflow_program_error_;
  std::string name_;
  unsigned capacity_;
  unsigned reserved_;
  std::deque<DataBuffer*> fifo_;
};

// Scalar valued fifo with value type ElementType.
template <typename ElementType>
using Fifo = StateItem<FifoBase, ElementType, FifoSourceOperand<ElementType>,
                       FifoDestinationOperand<ElementType>>;

// Fifo of N long vectors with element value type ElementType.
template <typename ElementType, int N>
using VectorFifo =
    StateItem<FifoBase, ElementType, FifoSourceOperand<ElementType>,
              FifoDestinationOperand<ElementType>, N>;

// Fifo of MxN sized matrices with element value type ElementType.
template <typename ElementType, int M, int N>
using MatrixFifo =
    StateItem<FifoBase, ElementType, FifoSourceOperand<ElementType>,
              FifoDestinationOperand<ElementType>, M, N>;

template <typename T, typename Enable>
std::vector<int> FifoSourceOperand<T, Enable>::shape() const {
  return fifo_->shape();
}

// Helper templates for the partial specialiations below.
template <typename T>
using EnableIfIntegral =
    typename std::enable_if<std::is_integral<T>::value, void>::type;

template <typename T>
using EnableIfNotIntegral =
    typename std::enable_if<!std::is_integral<T>::value, void>::type;

// Helper function used in the partial specialization below.
template <typename F, typename T,
          typename std::enable_if<std::is_signed<T>::value, T>::type* = nullptr>
inline T HelperAs(const FifoBase* fifo, int i) {
  DataBuffer* db = fifo->Front();
  if (nullptr == db) {
    return static_cast<T>(0);
  }

  return static_cast<T>(db->Get<typename std::make_signed<F>::type>(i));
}

template <
    typename F, typename T,
    typename std::enable_if<std::is_unsigned<T>::value, T>::type* = nullptr>
inline T HelperAs(const FifoBase* fifo, int i) {
  DataBuffer* db = fifo->Front();
  if (nullptr == db) {
    return static_cast<T>(0);
  }

  return static_cast<T>(db->Get<typename std::make_unsigned<F>::type>(i));
}

template <typename T, typename Enable>
FifoSourceOperand<T, Enable>::FifoSourceOperand(FifoBase* fifo,
                                                const std::string op_name)
    : fifo_(fifo), op_name_(op_name) {}

template <typename T, typename Enable>
FifoSourceOperand<T, Enable>::FifoSourceOperand(FifoBase* fifo)
    : FifoSourceOperand(fifo, fifo->name()) {}

template <typename T>
class FifoSourceOperand<T, EnableIfIntegral<T>>
    : public SourceOperandInterface {
 public:
  // Constructors. Note, default constructor deleted.
  FifoSourceOperand(FifoBase* fifo, const std::string op_name)
      : fifo_(fifo), op_name_(op_name) {}
  explicit FifoSourceOperand(FifoBase* fifo)
      : FifoSourceOperand(fifo, fifo->name()) {}
  FifoSourceOperand() = delete;

  // These accessor methods are defined to satisfy the interface. However,
  // in many cases, the purpose of the fifo is only to hold the underlying
  // DataBuffer instance, until popped in its entirety. It is therefore
  // expected that these accessors will not be used much.
  // Accessor methods call into the fifo_ data_buffer to obtain the values.
  // The index is in one dimension. For scalar registers it should always be
  // zero, for vector registers it is the element index. For higher order
  // register shapes it should be the linearized row-major order index.
  bool AsBool(int i) override { return HelperAs<T, bool>(fifo_, i); }
  int8_t AsInt8(int i) override { return HelperAs<T, int8_t>(fifo_, i); }
  uint8_t AsUint8(int i) override { return HelperAs<T, uint8_t>(fifo_, i); }
  int16_t AsInt16(int i) override { return HelperAs<T, int16_t>(fifo_, i); }
  uint16_t AsUint16(int i) override { return HelperAs<T, uint16_t>(fifo_, i); }
  int32_t AsInt32(int i) override { return HelperAs<T, int32_t>(fifo_, i); }
  uint32_t AsUint32(int i) override { return HelperAs<T, uint32_t>(fifo_, i); }
  int64_t AsInt64(int i) override { return HelperAs<T, int64_t>(fifo_, i); }
  uint64_t AsUint64(int i) override { return HelperAs<T, uint64_t>(fifo_, i); }

  // Returns the FifoBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(fifo_); }

  // Returns the shape of the fifo elements.
  std::vector<int> shape() const override { return fifo_->shape(); }

  std::string AsString() const override { return op_name_; }

 private:
  FifoBase* fifo_;
  std::string op_name_;
};

// This is a partial specialization of the Source operand class. This is used
// when the element type stored in the data buffer is not an integral type. This
// is primarily for when the fifo element type really doesn't model a register
// value per se, but a more complex structure such as a dma descriptor. In this
// case, the value interface is not intended to be used, but instead the fifo
// is accessed by using the GetObject and casting it to the appropriate type in
// order to access the source element.
template <typename T>
class FifoSourceOperand<T, EnableIfNotIntegral<T>>
    : public SourceOperandInterface {
 public:
  // Constructors. Note, default constructor deleted.
  FifoSourceOperand(FifoBase* fifo, const std::string op_name)
      : fifo_(fifo), op_name_(op_name) {}
  explicit FifoSourceOperand(FifoBase* fifo)
      : FifoSourceOperand(fifo, fifo->name()) {}
  FifoSourceOperand() = delete;

  // These accessor methods are defined to satisfy the interface.
  bool AsBool(int) override { return false; }
  int8_t AsInt8(int i) override { return 0; }
  uint8_t AsUint8(int i) override { return 0; }
  int16_t AsInt16(int i) override { return 0; }
  uint16_t AsUint16(int i) override { return 0; }
  int32_t AsInt32(int i) override { return 0; }
  uint32_t AsUint32(int i) override { return 0; }
  int64_t AsInt64(int i) override { return 0; }
  uint64_t AsUint64(int i) override { return 0; }

  std::string AsString() const override { return fifo_->name(); }

  // Returns the FifoBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(fifo_); }

  // Returns the shape of the fifo elements.
  std::vector<int> shape() const override { return fifo_->shape(); }

 private:
  FifoBase* fifo_;
  std::string op_name_;
};

template <typename T>
FifoDestinationOperand<T>::FifoDestinationOperand(FifoBase* fifo, int latency,
                                                  std::string op_name)
    : fifo_(fifo),
      db_factory_(fifo->arch_state()->db_factory()),
      latency_(latency),
      delay_line_(fifo->arch_state()->data_buffer_delay_line()),
      op_name_(op_name) {}

template <typename T>
FifoDestinationOperand<T>::FifoDestinationOperand(FifoBase* fifo, int latency)
    : FifoDestinationOperand(fifo, latency, fifo->name()) {}

template <typename T>
void FifoDestinationOperand<T>::InitializeDataBuffer(DataBuffer* db) {
  db->set_destination(fifo_);
  db->set_latency(latency_);
  db->set_delay_line(delay_line_);
}

template <typename T>
DataBuffer* FifoDestinationOperand<T>::AllocateDataBuffer() {
  DataBuffer* db = db_factory_->Allocate(fifo_->size());
  InitializeDataBuffer(db);
  return db;
}

template <typename T>
std::vector<int> FifoDestinationOperand<T>::shape() const {
  return fifo_->shape();
}

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

#endif  // MPACT_SIM_GENERIC_FIFO_H_
