// 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
//
//     http://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 "cheriot/profiler.h"

#include <cstdint>
#include <cstring>
#include <ostream>
#include <utility>

#include "absl/log/log.h"
#include "absl/numeric/bits.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "elfio/elf_types.hpp"

namespace mpact::sim::cheriot {

Profiler::Profiler(ElfProgramLoader &elf_loader, unsigned granularity)
    : elf_loader_(&elf_loader) {
  if (!absl::has_single_bit(granularity)) {
    LOG(ERROR) << absl::StrCat("Invalid granularity: ", granularity,
                               ",  must be a power of 2");
  }
  shift_ = absl::bit_width(granularity) - 1;
  SetElfLoader(&elf_loader);
}

Profiler::Profiler(unsigned granularity) : elf_loader_(nullptr) {
  if (!absl::has_single_bit(granularity)) {
    LOG(ERROR) << absl::StrCat("Invalid granularity: ", granularity,
                               ",  must be a power of 2");
  }
  shift_ = absl::bit_width(granularity) - 1;
}

Profiler::~Profiler() {
  for (auto const &[unused, counters] : profile_ranges_) {
    delete[] counters;
  }
  profile_ranges_.clear();
}

void Profiler::AddSampleInternal(uint64_t sample) {
  if (elf_loader_ == nullptr) return;
  // Look up a new range.
  auto it = profile_ranges_.find({sample, sample});
  if (it == profile_ranges_.end()) {
    LOG(WARNING) << absl::StrCat("Profile sample out of range: ",
                                 absl::Hex(sample << shift_));
    return;
  }
  // Save the range info and increment the counter.
  last_profile_range_ = it->second;
  last_start_ = it->first.start;
  last_end_ = it->first.end;
  last_profile_range_[sample - last_start_]++;
}

void Profiler::WriteProfile(std::ostream &os) {
  os << "Address,Count" << "\n";
  for (auto const &[range, counters] : profile_ranges_) {
    uint64_t size = range.end - range.start;
    for (auto i = 0; i < size; ++i) {
      if (counters[i] == 0) continue;
      os << absl::StrFormat("0x%llx,%llu\n", (range.start + i) << shift_,
                            counters[i]);
    }
  }
}

void Profiler::SetElfLoader(ElfProgramLoader *elf_loader) {
  elf_loader_ = elf_loader;
  uint64_t begin = 0;
  uint64_t end = 0;
  // Iterate through the elf segments (assumes they are in order), and
  // coalesces ranges that are spaced by less than 0x1'000 units of granularity.
  // This reduces the number of ranges in the map and improves performance
  // during simulation.
  for (auto const &segment : elf_loader_->elf_reader()->segments) {
    // Only consider segments that are loaded, executable, and with size > 0.
    if (segment->get_type() != PT_LOAD) continue;
    if ((segment->get_flags() & PF_X) == 0) continue;
    uint64_t size = segment->get_memory_size() >> shift_;
    if (size == 0) continue;

    uint64_t vaddr_begin = segment->get_virtual_address() >> shift_;
    // If it's the first time we see a segment, just get the start and end
    // values.
    if (begin == 0 && end == 0) {
      begin = vaddr_begin;
      end = vaddr_begin + size;
      continue;
    };
    // If the segment is close enough to the current, just coalesce.
    if (vaddr_begin - end < 0x1000) {
      end = vaddr_begin + size;
      continue;
    }
    // Otherwise, create a entry from the previously accumulated ranges, and
    // start a new range.
    size = end - begin - 1;
    uint64_t *counters = new uint64_t[size];
    ::memset(counters, 0, size * sizeof(uint64_t));
    profile_ranges_.insert(std::make_pair(AddressRange{begin, end}, counters));
    begin = vaddr_begin;
    end = vaddr_begin + size;
  }
  // Make the last entry.
  if (begin != 0 || end != 0) {
    uint64_t size = end - begin - 1;
    uint64_t *counters = new uint64_t[size];
    ::memset(counters, 0, size * sizeof(uint64_t));
    profile_ranges_.insert(
        std::make_pair(AddressRange{begin, end - 1}, counters));
  }
}

}  // namespace mpact::sim::cheriot
