// 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_DELAY_LINE_H_
#define MPACT_SIM_GENERIC_DELAY_LINE_H_

#include <vector>

/* Commented out for now. Not currently using threads.
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
*/
#include "absl/numeric/bits.h"
#include "mpact/sim/generic/delay_line_interface.h"

namespace mpact {
namespace sim {
namespace generic {

// The DelayLine is the generic class for implementing delay lines for
// values and deferred function calls. It allows one or more "actions" to
// be scheduled to be performed a number of cycles (calls to Advance()) in
// the future. The exact action to be performed is determined by the template
// parameter type DelayRecord. Abstractly, the DelayLine class is a circular
// buffer of lists of DelayRecords. It is implemented as a vector
// of vectors of DelayRecord instances. A given index into the first dimension
// contains a vector of the set of DelayRecord instances that specifies the
// "actions" that are performed for a given cycle in the future (based on its
// distance from the current_ index (mod vector size).
//
// The DelayLine circular buffer is always a power of two to make the
// mod operator cheap.
//
// The DelayLine class can be instantiated by passing in the DelayRecord
// type as a template argument. The DelayRecord must have a void Apply()
// method that performs the actions intended once the delay line has advanced
// to that record. Additionally, the DelayRecord type must have a constructor
// that can be called by std::vector::emplace_back().
//
// For instance, if the DelayRecord consists of a pointer and a value (with the
// intent that after a delay, the value gets written to the object pointed to
// by that pointer) a reasonable DelayRecord would be.
//
// struct MyDelayRecord {
//   int *destination;
//   int value;
//   void Apply() {
//     *destination = value;
//   }
//   MyDelayRecord(int *dest, int val) : destination(dest), value(val) {}
// };
//
// This class is thread safe.
template <typename DelayRecord>
class DelayLine : public DelayLineInterface {
 public:
  constexpr static int kDefaultDelayLineDepth = 16;
  // Constructor that takes an initial minimum size
  explicit DelayLine(uint32_t min_size)
      : delay_line_(absl::bit_ceil(min_size)), current_(0), num_entries_(0) {
    mask_ = delay_line_.size() - 1;
  }

  // Default constructor and destructors
  DelayLine() : DelayLine(kDefaultDelayLineDepth) {}
  ~DelayLine() override = default;

  // Add an item to the delay line with the given latency. The Ts... argument
  // pack is the set of arguments to the constructor of the DelayRecord which
  // is the value record type for the DelayLine. Returns the total number of
  // valid elements.
  template <typename... Ts>
  int Add(int latency, Ts... args) /*ABSL_LOCKS_EXCLUDED(delay_line_lock_)*/ {
    // absl::MutexLock dl(&delay_line_lock_);
    // If the latency is longer than the delay line, resize the delay line.
    if (latency >= static_cast<int>(delay_line_.size())) {
      Resize(latency);
    }
    int pos = (latency + current_) & mask_;
    delay_line_[pos].emplace_back(args...);
    return ++num_entries_;
  }

  // Advances the delay line by a cycle and performs any actions required.
  // Depending on the record type R, the actual action may vary. The initial
  // actions supported generically are writing back a data buffer to a state
  // instance and calling a function. Additional actions can be created by
  // deriving new delay lines as needed. Returns the number of valid entries
  // left in the delay line.
  int Advance() override /*ABSL_LOCKS_EXCLUDED(delay_line_lock_)*/ {
    // absl::MutexLock dl(&delay_line_lock_);
    current_ = (current_ + 1) & mask_;
    for (auto &rec : delay_line_[current_]) {
      rec.Apply();
      num_entries_--;
    }
    delay_line_[current_].clear();
    return num_entries_;
  }

  // Returns true if the delay line is empty.
  bool IsEmpty() const override { return num_entries_ == 0; }

 private:
  // If the latency is >= the delay line length, the delay line has to be
  // resized so the latency is covered.
  void Resize(
      uint32_t min_size) /*ABSL_EXCLUSIVE_LOCKS_REQUIRED(delay_line_lock_)*/ {
    // Compute a new size that's >= min_size and is a power of 2
    // Given that the initial size is a power of two, multiplying the
    // current size by two until it's greater or equal to min_size is
    // sufficient.
    uint32_t prev_size = delay_line_.size();

    if (min_size < prev_size) {
      return;
    }

    uint32_t new_size = absl::bit_ceil(min_size);

    mask_ = new_size - 1;
    delay_line_.resize(new_size);

    // now need to move elements from 0 to current-1 to new locations.
    for (int index = 0; index < current_; ++index) {
      if (!delay_line_[index].empty()) {
        delay_line_[prev_size + index] = delay_line_[index];
        delay_line_[index].clear();
      }
    }
  }

  std::vector<std::vector<DelayRecord>> delay_line_;
  /*ABSL_GUARDED_BY(delay_line_lock_)*/
  int current_ /*ABSL_GUARDED_BY(delay_line_lock_)*/;
  int mask_ /*ABSL_GUARDED_BY(delay_line_lock_)*/;
  /*absl::Mutex delay_line_lock_;*/
  uint32_t num_entries_;
};

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

#endif  // MPACT_SIM_GENERIC_DELAY_LINE_H_
