// Copyright 2024 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/util/memory/cache.h"

#include <unistd.h>

#include <cstdint>
#include <limits>
#include <string>
#include <vector>

#include "absl/functional/bind_front.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/numeric/bits.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/component.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/tagged_memory_interface.h"

namespace mpact::sim::util {

using ::mpact::sim::generic::Component;

// Constructors.
Cache::Cache(std::string name, Component *parent, MemoryInterface *memory)
    : Component(name, parent),
      read_hit_counter_("read_hit", 0ULL),
      read_miss_counter_("read_miss", 0ULL),
      write_hit_counter_("write_hit", 0ULL),
      write_miss_counter_("write_miss", 0ULL),
      dirty_line_writeback_counter_("dirty_line_writeback", 0ULL),
      read_around_counter_("read_around", 0ULL),
      write_around_counter_("write_around", 0ULL),
      read_non_cacheable_counter_("read_non_cacheable", 0ULL),
      write_non_cacheable_counter_("write_non_cacheable", 0ULL),
      memory_(memory),
      tagged_memory_(nullptr) {
  // Register the counters.
  CHECK_OK(AddCounter(&read_hit_counter_));
  CHECK_OK(AddCounter(&read_miss_counter_));
  CHECK_OK(AddCounter(&write_hit_counter_));
  CHECK_OK(AddCounter(&write_miss_counter_));
  CHECK_OK(AddCounter(&dirty_line_writeback_counter_));
  CHECK_OK(AddCounter(&read_around_counter_));
  CHECK_OK(AddCounter(&write_around_counter_));
  CHECK_OK(AddCounter(&read_non_cacheable_counter_));
  CHECK_OK(AddCounter(&write_non_cacheable_counter_));
  cache_inst_ = new Instruction(nullptr);
  cache_inst_->set_semantic_function(absl::bind_front(&Cache::LoadChild, this));
}

Cache::Cache(std::string name, Component *parent,
             TaggedMemoryInterface *tagged_memory)
    : Component(name, parent),
      read_hit_counter_("read_hit", 0ULL),
      read_miss_counter_("read_miss", 0ULL),
      write_hit_counter_("write_hit", 0ULL),
      write_miss_counter_("write_miss", 0ULL),
      dirty_line_writeback_counter_("dirty_line_writeback", 0ULL),
      read_around_counter_("read_around", 0ULL),
      write_around_counter_("write_around", 0ULL),
      memory_(tagged_memory),
      tagged_memory_(tagged_memory) {
  // Register the counters.
  CHECK_OK(AddCounter(&read_hit_counter_));
  CHECK_OK(AddCounter(&read_miss_counter_));
  CHECK_OK(AddCounter(&write_hit_counter_));
  CHECK_OK(AddCounter(&write_miss_counter_));
  CHECK_OK(AddCounter(&dirty_line_writeback_counter_));
  CHECK_OK(AddCounter(&read_around_counter_));
  CHECK_OK(AddCounter(&write_around_counter_));
  CHECK_OK(AddCounter(&read_non_cacheable_counter_));
  CHECK_OK(AddCounter(&write_non_cacheable_counter_));
  cache_inst_ = new Instruction(nullptr);
  cache_inst_->set_semantic_function(absl::bind_front(&Cache::LoadChild, this));
}

// The simple constructors just call the main constructors.
Cache::Cache(std::string name, MemoryInterface *memory)
    : Cache(name, nullptr, memory) {}

Cache::Cache(std::string name, TaggedMemoryInterface *tagged_memory)
    : Cache(name, nullptr, tagged_memory) {}

Cache::Cache(std::string name, Component *parent)
    : Cache(name, parent, static_cast<MemoryInterface *>(nullptr)) {}

Cache::Cache(std::string name)
    : Cache(name, static_cast<Component *>(nullptr)) {}

Cache::~Cache() {
  delete[] cache_lines_;
  cache_inst_->DecRef();
}

absl::Status Cache::Configure(const std::string &config,
                              CounterValueOutputBase<uint64_t> *cycle_counter) {
  if (cycle_counter == nullptr) {
    return absl::InvalidArgumentError("Cycle counter is null");
  }
  cycle_counter_ = cycle_counter;
  // Split the configuration string into fields, make sure there are 4 fields.
  std::vector<std::string> config_vec = absl::StrSplit(config, ',');
  if (config_vec.size() < 4) {
    return absl::InvalidArgumentError("Invalid configuration - too few fields");
  }
  // Compute the cache size in bytes, including any suffixes ('k', 'M', 'G').
  std::string::size_type size;
  uint64_t cache_size = std::stoull(config_vec[0], &size);
  if (size < config_vec[0].size()) {
    auto suffix = config_vec[0].substr(size);
    if (suffix == "k") {
      cache_size *= 1024;
    } else if (suffix == "M") {
      cache_size *= 1024 * 1024;
    } else if (suffix == "G") {
      cache_size *= 1024 * 1024 * 1024;
    } else {
      return absl::InvalidArgumentError(
          absl::StrCat("Invalid cache size suffix: '", suffix, "'"));
    }
  }
  // Line size in bytes.
  uint64_t line_size = std::stoull(config_vec[1], &size);
  if (size != config_vec[1].size()) {
    return absl::InvalidArgumentError("Invalid value for line size");
  }
  // Number of sets (set associativity) - 0 means fully set associative.
  num_sets_ = std::stoull(config_vec[2], &size);
  if (size != config_vec[2].size()) {
    return absl::InvalidArgumentError("Invalid value for number of sets");
  }
  // Write allocate.
  if (config_vec[3] == "true") {
    write_allocate_ = true;
  } else if (config_vec[3] == "false") {
    write_allocate_ = false;
  } else {
    return absl::InvalidArgumentError("Invalid write allocate value");
  }
  // If there are more than 4 entries, check for cacheable, or non-cacheable
  // memory ranges. Format is: [c|nc]:<start_address>:<size>
  for (int i = 4; i < config_vec.size(); i++) {
    std::vector<std::string> range_vec = absl::StrSplit(config_vec[i], ':');
    if (range_vec.size() != 3) {
      return absl::InvalidArgumentError(
          "Invalid (non)cacheable range - must have 3 fields");
    }
    uint64_t range_start = std::stoull(range_vec[1], &size, 0);
    if (size != range_vec[1].size()) {
      return absl::InvalidArgumentError(
          "Invalid cacheable range - invalid start address");
    }
    uint64_t range_end = std::stoull(range_vec[2], &size, 0);
    if (size != range_vec[2].size()) {
      return absl::InvalidArgumentError(
          "Invalid cacheable range - invalid size");
    }
    if (range_start > range_end) {
      return absl::InvalidArgumentError(
          "Invalid cacheable range - start address is greater than end "
          "address");
    }
    if ((range_vec[0] != "c") && (range_vec[0] != "nc")) {
      return absl::InvalidArgumentError(
          "Invalid cacheable range - must start with 'c' or 'nc'");
    }
    if (range_vec[0] == "c") {
      if (!non_cacheable_ranges_.empty()) {
        return absl::InvalidArgumentError(
            "Cannot mix cacheable and non-cacheable ranges");
      }
      cacheable_ranges_.insert(AddressRange(range_start, range_end));
      has_cacheable_ = true;
    } else {
      if (!cacheable_ranges_.empty()) {
        return absl::InvalidArgumentError(
            "Cannot mix cacheable and non-cacheable ranges");
      }
      non_cacheable_ranges_.insert(AddressRange(range_start, range_end));
      has_non_cacheable_ = true;
    }
  }
  // Sanity check more cache parameters.
  if (!absl::has_single_bit(cache_size)) {
    return absl::InvalidArgumentError("Cache size is not a power of 2");
  }
  if (!absl::has_single_bit(line_size)) {
    return absl::InvalidArgumentError("Line size is not a power of 2");
  }
  if (num_sets_ != 0 && !absl::has_single_bit(num_sets_)) {
    return absl::InvalidArgumentError("Number of sets is not a power of 2");
  }
  if (cache_size == 0) {
    return absl::InvalidArgumentError("Cache size is zero");
  }
  if (line_size < 4) {
    return absl::InvalidArgumentError("Line size must be at least 4 bytes");
  }
  if (cache_size < line_size) {
    return absl::InvalidArgumentError("Cache size is less than line size");
  }
  // If num_sets is 0, then the cache is fully associative.
  if (num_sets_ == 0) {
    num_sets_ = cache_size / line_size;
  }
  uint64_t num_lines = cache_size / line_size;
  if (num_sets_ > num_lines) {
    return absl::InvalidArgumentError(
        "Cache associativity is greater than the number of lines");
  }
  delete[] cache_lines_;
  cache_lines_ = new CacheLine[num_lines];
  block_shift_ = absl::bit_width(line_size) - 1;
  index_mask_ = (1ULL << (absl::bit_width(num_lines / num_sets_) - 1)) - 1;
  set_shift_ = absl::bit_width(num_sets_) - 1;
  return absl::OkStatus();
}

// Each of the following memory (and tagged memory) interface methods will call
// the CacheLookup method to perform the cache access. If the access is a miss,
// the method will call the ReplaceBlock method to replace the block in the
// cache. The memory request itself will be forwarded to the memory interface
// provided to the constructor (if not nullptr).
void Cache::Load(uint64_t address, DataBuffer *db, Instruction *inst,
                 ReferenceCount *context) {
  (void)CacheLookup(address, db->size<uint8_t>(), /*is_read=*/true);

  if (memory_ == nullptr) return;

  auto *cache_context = new CacheContext(context, db, inst, db->latency());
  if (context) context->IncRef();
  if (inst) inst->IncRef();
  db->IncRef();
  db->set_latency(0);
  memory_->Load(address, db, cache_inst_, cache_context);
  cache_context->DecRef();
}

void Cache::Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
                 DataBuffer *db, Instruction *inst, ReferenceCount *context) {
  auto address_span = address_db->Get<uint64_t>();
  auto mask_span = mask_db->Get<bool>();
  for (int i = 0; i < address_db->size<uint64_t>(); i++) {
    if (mask_span[i]) {
      (void)CacheLookup(address_span[i], el_size, /*is_read=*/true);
    }
  }
  if (memory_ == nullptr) return;

  auto *cache_context = new CacheContext(context, db, inst, db->latency());
  if (context) context->IncRef();
  if (inst) inst->IncRef();
  db->IncRef();
  db->set_latency(0);
  memory_->Load(address_db, mask_db, el_size, db, cache_inst_, cache_context);
  cache_context->DecRef();
}

void Cache::Load(uint64_t address, DataBuffer *db, DataBuffer *tags,
                 Instruction *inst, ReferenceCount *context) {
  // Since db can be nullptr (for a tag only load), the size and latency may
  // have to be computed differently. For size, base it on the number of tags
  // that are being loaded. For latency, use 0.
  int size = 0;
  if (db == nullptr) {
    int num_tags = tags->size<uint8_t>();
    size = (address & ~0x7ULL) + (num_tags << 3) - address;
  } else {
    size = db->size<uint8_t>();
  }
  int latency = (db != nullptr) ? db->latency() : tags->latency();

  (void)CacheLookup(address, size, /*is_read=*/true);
  if (tagged_memory_ == nullptr) return;

  if (inst == nullptr) {  // Just forward and return.
    tagged_memory_->Load(address, db, tags, /*inst=*/nullptr, context);
    return;
  }

  auto *cache_context = new CacheContext(context, db, inst, latency);
  if (context) context->IncRef();
  if (inst) inst->IncRef();
  if (db) {
    db->set_latency(0);
    db->IncRef();
  }
  tagged_memory_->Load(address, db, tags, cache_inst_, cache_context);
  cache_context->DecRef();
}

void Cache::Store(uint64_t address, DataBuffer *db) {
  (void)CacheLookup(address, db->size<uint8_t>(), /*is_read=*/false);
  if (memory_ == nullptr) return;

  memory_->Store(address, db);
}

void Cache::Store(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
                  DataBuffer *db) {
  auto address_span = address_db->Get<uint64_t>();
  auto mask_span = mask_db->Get<bool>();
  for (int i = 0; i < address_db->size<uint64_t>(); i++) {
    if (mask_span[i]) {
      (void)CacheLookup(address_span[i], el_size, /*is_read=*/false);
    }
  }
  if (memory_ == nullptr) return;

  memory_->Store(address_db, mask_db, el_size, db);
}

void Cache::Store(uint64_t address, DataBuffer *db, DataBuffer *tags) {
  (void)CacheLookup(address, db->size<uint8_t>(), /*is_read=*/false);
  if (tagged_memory_ == nullptr) return;

  tagged_memory_->Store(address, db, tags);
}

// This is the semantic function that is bound to the cache_inst_ instruction
// and is used to perform the writeback to the processor of the data that was
// read.
void Cache::LoadChild(const Instruction *inst) {
  auto *cache_context = static_cast<CacheContext *>(inst->context());
  auto *og_context = cache_context->context;
  auto *db = cache_context->db;
  auto *og_inst = cache_context->inst;
  // Reset the db latency to the original value.
  if (nullptr != og_inst) {
    if (cache_context->latency > 0) {
      if (db != nullptr) db->set_latency(cache_context->latency);
      og_inst->state()->function_delay_line()->Add(
          db->latency(), [og_inst, og_context]() {
            og_inst->Execute(og_context);
            if (og_context != nullptr) og_context->DecRef();
            og_inst->DecRef();
          });
    } else {
      og_inst->Execute(og_context);
      if (og_context != nullptr) og_context->DecRef();
      og_inst->DecRef();
    }
  }
  if (db) db->DecRef();
}

// Cache lookup function.
int Cache::CacheLookup(uint64_t address, int size, bool is_read) {
  int miss_count = 0;
  // If the size spans more than one block, perform and access for each block.
  uint64_t first_block = address >> block_shift_;
  uint64_t last_block = (address + size - 1) >> block_shift_;
  for (uint64_t block = first_block; block <= last_block; block++) {
    // Check each access to see if it is cachaeable or not.
    if (has_cacheable_ || has_non_cacheable_) {
      bool dont_fetch =
          (has_cacheable_ && !cacheable_ranges_.contains(
                                 AddressRange(address, address + size - 1))) ||
          (has_non_cacheable_ && non_cacheable_ranges_.contains(AddressRange(
                                     address, address + size - 1)));
      if (dont_fetch) {
        // Perform read/write-around.
        if (is_read) {
          read_non_cacheable_counter_.Increment(1ULL);
        } else {
          write_non_cacheable_counter_.Increment(1ULL);
        }
        // Skip the below since it's not cacheable.
        continue;
      }
    }

    // Compute the cache index.
    uint64_t index = (block & index_mask_) << set_shift_;
    bool hit = false;
    // Iterate over the number of sets in the cache.
    for (int set = 0; set < num_sets_; set++) {
      CacheLine &line = cache_lines_[index + set];
      if (line.valid && line.tag == block) {
        hit = true;
        line.lru = cycle_counter_->GetValue();
        line.dirty |= !is_read;
        break;
      }
    }
    if (hit) {
      if (is_read) {
        read_hit_counter_.Increment(1ULL);
      } else {
        write_hit_counter_.Increment(1ULL);
      }
    } else {
      if (is_read) {
        ReplaceBlock(block, /*is_read=*/true);
        miss_count++;
        read_miss_counter_.Increment(1ULL);
      } else {
        write_miss_counter_.Increment(1ULL);
        if (write_allocate_) {
          ReplaceBlock(block, /*is_read=*/false);
          miss_count++;
        } else {
          write_around_counter_.Increment(1ULL);
        }
      }
    }
  }
  return miss_count;
}

void Cache::ReplaceBlock(uint64_t block, bool is_read) {
  // Recompute the cache index.
  uint64_t index = (block & index_mask_) << set_shift_;
  int victim = -1;
  uint64_t victim_lru = std::numeric_limits<uint64_t>::max();
  for (int set = 0; set < num_sets_; set++) {
    CacheLine &line = cache_lines_[index + set];
    // If the line is invalid, use it as the victim.
    if (!line.valid) {
      victim = index + set;
      break;
    }
    // Skip any pinned lines.
    if (line.pinned) continue;
    // See if the next line has a smaller lru timestamp, if so, make that the
    // victim.
    if (line.lru < victim_lru) {
      victim = index + set;
      victim_lru = line.lru;
    }
  }
  // If there is no victim, that means the lines were pinned, so couldn't
  // replace. In this case the miss really becomes a read/write around.
  if (victim == -1) {
    if (is_read) {
      read_around_counter_.Increment(1ULL);
    } else {
      write_around_counter_.Increment(1ULL);
    }
    return;
  }
  // Perform the replacement on the victim.
  CacheLine &line = cache_lines_[victim];
  // If the line is dirty (and valid), count the writeback.
  if (line.valid && line.dirty) {
    dirty_line_writeback_counter_.Increment(1ULL);
  }
  // Initialize the new line.
  line.valid = true;
  line.tag = block;
  line.pinned = false;
  line.dirty = false;
  line.lru = cycle_counter_->GetValue();
}

}  // namespace mpact::sim::util
