// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/zxdump/task.h>

#include <algorithm>
#include <cinttypes>
#include <cstdio>
#include <memory>
#include <new>

#include "buffer-impl.h"
#include "dump-file.h"

namespace zxdump {
namespace {

class AlignedBufferImpl final : public internal::BufferImpl {
 public:
  AlignedBufferImpl(std::align_val_t alignment, size_t size)
      : alignment_{alignment},
        size_{size},
        ptr_(static_cast<std::byte*>(operator new[](size_, alignment_))) {}

  ~AlignedBufferImpl() { operator delete[](ptr_, size_, alignment_); }

  std::byte* get() const { return ptr_; }

 private:
  std::align_val_t alignment_;
  std::size_t size_;
  std::byte* ptr_;
};

}  // namespace

fit::result<Error, Buffer<>> Process::ReadMemoryImpl(uint64_t vaddr, size_t size,
                                                     ReadMemorySize size_mode, size_t alignment) {
  auto read_dump_memory = [this, vaddr, size, size_mode]() -> fit::result<Error, Buffer<>> {
    auto possible = [vaddr](const auto& elt) -> bool {
      const auto& [segment_vaddr, segment] = elt;
      return segment_vaddr + segment.memsz <= vaddr;
    };

    auto found = std::partition_point(memory_.begin(), memory_.end(), possible);
    if (found != memory_.end()) {
      const auto& [segment_vaddr, segment] = *found;
      if (vaddr >= segment_vaddr && vaddr - segment_vaddr < segment.memsz) {
        // This segment covers the address.

        if (segment.filesz <= vaddr - segment_vaddr || !dump_) {
          // The portion of this segment we need was elided, or the whole dump
          // was inserted with read_memory=false,
          return fit::ok(Buffer<>{});
        }

        // Map the segment to a region of the file.
        internal::FileRange where = {segment.offset, segment.filesz};
        where %= vaddr - segment_vaddr;

        // If the next segment is contiguous we can fetch across them.
        while (++found != memory_.end() && found->first == vaddr + where.size &&
               found->second.offset == where.offset + where.size) {
          where.size += found->second.filesz;
        }

        auto result = dump_->ReadMemory(where);
        if (result.is_error()) {
          return result.take_error();
        }
        Buffer<> buffer = *std::move(result);
        ZX_ASSERT(buffer->size_bytes() >= size);
        if (size_mode == ReadMemorySize::kExact) {
          buffer.data_ = buffer.data_.subspan(0, size);
        }

        return fit::ok(std::move(buffer));
      }
    }

    return fit::error(Error{"no such memory", ZX_ERR_NO_MEMORY});
  };

  auto result = live() ? ReadLiveMemory(vaddr, size, size_mode) : read_dump_memory();

  // When reading a job archive, the segment.offset has been adjusted by
  // the process dump file's position in the archive, so file offsets may
  // no longer be aligned as they were in the ELF file.  So even a request
  // at a properly-aligned vaddr might yield a file buffer that's not
  // aligned.  It's also possible that the live memory cache's pages didn't
  // actually get allocated locally as page-aligned, and the requested
  // alignment exceeds the alignment of the page buffer.  In these cases,
  // just copy to an aligned buffer.
  if (alignment > 1 && result.is_ok()) {
    // Keep the Buffer<> holder and just update what it holds (if necessary).
    Buffer<>& buffer = *result;

    // Only copy the requested data even in ReadMemorySize::kMore mode.
    const size_t result_size = std::min(size, buffer->size_bytes());

    // Check if it's not already as aligned as it needs to be.
    void* align_ptr = const_cast<std::byte*>(buffer->data());
    size_t align_space = result_size;
    if (!std::align(alignment, result_size, align_ptr, align_space)) {
      // Copy the contents into a fresh, aligned buffer.
      auto impl = std::make_unique<AlignedBufferImpl>(std::align_val_t{alignment}, size);
      memcpy(impl->get(), buffer->data(), result_size);
      buffer.data_ = {impl->get(), result_size};
      // Note this may free the old buffer, so it must be after the copying.
      buffer.impl_ = std::move(impl);
    }
  }

  return result;
}

}  // namespace zxdump
