// 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_ARCH_STATE_H_
#define MPACT_SIM_GENERIC_ARCH_STATE_H_

#include <string>
#include <type_traits>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/component.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/delay_line_interface.h"
#include "mpact/sim/generic/function_delay_line.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/program_error.h"

namespace mpact {
namespace sim {
namespace generic {

class RegisterBase;
class FifoBase;

// The ArchState class is a "glue" class for the simulated architecture state.
// It is intended that it be used to derive a class for each specific
// architecture for which a simulator is created, adding any specific features
// that is needed for that class.
//
// All delay lines, registers and fifo's are registered with the ArchState
// instance used in a simulator. The ArchState instance can then be called
// to advance delay lines, and look up register and fifo instances.
class ArchState : public Component {
  // ArchState is supposed to be instantiated from a derived class specific
  // to the architecture that is to be simulated. Default constructor is
  // disabled.
 protected:
  ArchState() = delete;
  explicit ArchState(absl::string_view id) : ArchState(nullptr, id, nullptr) {}
  ArchState(absl::string_view id, SourceOperandInterface *pc_operand)
      : ArchState(nullptr, id, pc_operand) {}
  ArchState(Component *parent, absl::string_view id,
            SourceOperandInterface *pc_operand);

 public:
  ~ArchState() override;

 public:
  using RegisterMap = absl::flat_hash_map<const std::string, RegisterBase *>;
  using FifoMap = absl::flat_hash_map<const std::string, FifoBase *>;

  // Adds the given register to the register table.
  void AddRegister(RegisterBase *reg);
  // Adds the given register to the register table but using name as key. This
  // is useful when a register object may be accessible using more than one
  // name, or a name that differs from that stored in the register object.
  void AddRegister(absl::string_view name, RegisterBase *reg);
  // Remove the named register from the register table. No action occurs if
  // there is no such register. If multiple names map to the same register
  // object, only the single mapping from the given name is removed.
  void RemoveRegister(absl::string_view name);

  // Creates a register of the given type and adds it to the register table.
  template <typename RegisterType, typename... Ps>
  RegisterType *AddRegister(absl::string_view name, Ps... pargs) {
    auto reg = new RegisterType(this, name, pargs...);
    AddRegister(reg);
    return reg;
  }

  // Adds the given fifo to the fifo table.
  void AddFifo(FifoBase *fifo);
  // Adds the given fifo to the fifo table but using name as key. This is useful
  // when a fifo object may be accessed using more than one name, or a name that
  // differs from that stored in the fifo object.
  void AddFifo(absl::string_view name, FifoBase *fifo);
  // Remove the named fifo from the fifo table. No action occurs if there is no
  // such fifo. If multiple names map to the same fifo object, only the single
  // mapping from the given name is removed.
  void RemoveFifo(absl::string_view name);

  // Creates a fifo of the given type and adds it to the fifo table.
  template <typename FifoType, typename... Ps>
  FifoType *AddFifo(absl::string_view name, Ps... pargs) {
    auto fifo = new FifoType(this, name, pargs...);
    AddFifo(fifo);
    return fifo;
  }

  // Advance all registered delay lines by one cycle.
  inline void AdvanceDelayLines() {
    cycle_++;
    for (auto dl : delay_lines_) {
      dl->Advance();
    }
  }

  // Create and add a delay line of the given type. This provides a mechanism
  // to add additional delay lines for types other than data buffer instances
  // and void() function objects that will be advanced when the ArchState
  // delay lines are advanced. It is of course possible to create and manage
  // delay lines outside of ArchState instances. Delay lines managed by the
  // ArchState instance will be deleted when the ArchState is deleted.
  template <typename DelayLineType, typename... Ps>
  DelayLineType *CreateAndAddDelayLine(Ps... pargs) {
    static_assert(
        std::is_convertible<DelayLineType *, DelayLineInterface *>::value);
    DelayLineType *delay_line = new DelayLineType(pargs...);
    delay_lines_.push_back(static_cast<DelayLineInterface *>(delay_line));
    return delay_line;
  }

  // Accessors for data members
  const std::string &id() const { return component_name(); }
  // The DataBufferFactory associated with this architecture instance.
  DataBufferFactory *db_factory() const { return db_factory_; }
  // The table of registers.
  RegisterMap *registers() { return &registers_; }
  // The table of fifos.
  FifoMap *fifos() { return &fifos_; }
  // The DataBuffer instance delay line.
  DataBufferDelayLine *data_buffer_delay_line() const {
    return data_buffer_delay_line_;
  }
  // The void() function delay line
  FunctionDelayLine *function_delay_line() const {
    return function_delay_line_;
  }
  // Returns the PC operand interface (read only)
  SourceOperandInterface *pc_operand() const { return pc_operand_; }
  // Used to report program error (or even internal simulator errors).
  ProgramErrorController *program_error_controller() const {
    return program_error_controller_;
  }

  uint64_t cycle() const { return cycle_; }

 protected:
  void set_pc_operand(SourceOperandInterface *pc_operand) {
    pc_operand_ = pc_operand;
  }
  void set_cycle(uint64_t value) { cycle_ = value; }

 private:
  uint64_t cycle_ = 0;
  SourceOperandInterface *pc_operand_;
  DataBufferFactory *db_factory_;
  RegisterMap registers_;
  FifoMap fifos_;
  DataBufferDelayLine *data_buffer_delay_line_;
  FunctionDelayLine *function_delay_line_;
  std::vector<DelayLineInterface *> delay_lines_;
  ProgramErrorController *program_error_controller_;
};

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

#endif  // MPACT_SIM_GENERIC_ARCH_STATE_H_
