// Copyright 2020 The Chromium OS 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 "croslog/file_map_reader.h"

#include <algorithm>
#include <unistd.h>

#include "croslog/log_line_reader.h"

namespace croslog {

namespace {

// Size of chunk: 4 MB. This must be multiple of the page size.
// This is not constant for testing.
static uint64_t g_chunk_size_in_bytes = 4 * 1024 * 1024;
// Number of chunks to be allocated: 128 MB.
// This is not constant for testing.
static uint64_t g_allocate_chunk_size = 32;
// A dummy empty buffer. Used as an empty buffer.
static const uint8_t kEmptyBuffer[] = {};

std::pair<uint64_t, uint64_t> CalculateAppropriateBufferRange(
    uint64_t request_pos, uint64_t request_length, uint64_t file_size) {
  // Ensure the request parameters are valid. The caller must take care of it.
  DCHECK_LE(request_pos + request_length, file_size);

  // Assumption of this logic: the requested length is small enough to avoid
  // request size from overruning of the allocated buffer range.
  // The current limit is |g_chunk_size_in_bytes|, and this value is the limit
  // in the case of g_allocate_chunk_size == 2. This can be larger when
  // |g_allocate_chunk_size| > 2 (but currently it is not supported).
  DCHECK_LE(request_length, g_chunk_size_in_bytes);
  // Assumption of this logic: |g_allocate_chunk_size| must be larger than 2 to
  // allocate a buffer across two chunks.
  DCHECK_LE(2u, g_allocate_chunk_size);
  // Assumption of this logic: |g_allocate_chunk_size| must be multiple of the
  // page size, otherwise mmap fails.
  DCHECK_EQ(0, g_chunk_size_in_bytes % sysconf(_SC_PAGE_SIZE));

  // Calculate the aligned range of buffer with margins after and before.
  // Each margin is about ((g_allocate_chunk_size / 2) * g_chunk_size_in_bytes)
  // MB.
  uint64_t buffer_length = g_allocate_chunk_size * g_chunk_size_in_bytes;
  uint64_t buffer_start_pos =
      request_pos - (request_pos % g_chunk_size_in_bytes);

  // Add a margin before the requested range.
  buffer_start_pos -=
      std::min(buffer_start_pos,
               (g_allocate_chunk_size / 2 - 1) * g_chunk_size_in_bytes);

  // Adjust the length not to overrun the file size.
  if ((buffer_start_pos + buffer_length) > file_size)
    buffer_length = file_size - buffer_start_pos;

  // Ensure the calculated range is valid.
  DCHECK_LE(buffer_start_pos, request_pos);
  DCHECK_LE(request_pos + request_length, buffer_start_pos + buffer_length);

  return std::make_pair(buffer_start_pos, buffer_length);
}

}  // anonymous namespace

// ============================================================================
// FileMapReaderDelegate declaration:

// Delegate to implement the logic to map the file or something compatible.
class FileMapReaderDelegate {
 public:
  virtual ~FileMapReaderDelegate() = default;

  // Returns the current file size on the file system.
  virtual int64_t GetCurrentFileSize() = 0;

  // Do mmap and returns the allocated memory. Allocated memory is bigger than
  // the requested size with mergins and includes the requested range.
  // - On error, nullptr is returned
  // - On success, an allocated memory is owned by the delegate
  // An allocated memory is released on next DoMap call or dtor.
  virtual std::pair<const uint8_t*, uint64_t> DoMap(int64_t request_pos,
                                                    int64_t request_length) = 0;
};

// ============================================================================
// FileMapReaderDelegateImpl implementation:

class FileMapReaderDelegateImpl : public FileMapReaderDelegate {
 public:
  explicit FileMapReaderDelegateImpl(base::File file)
      : file_(std::move(file)) {}
  FileMapReaderDelegateImpl(const FileMapReaderDelegateImpl&) = delete;
  FileMapReaderDelegateImpl& operator=(const FileMapReaderDelegateImpl&) =
      delete;

  ~FileMapReaderDelegateImpl() override = default;

  int64_t GetCurrentFileSize() override { return file_.GetLength(); }

  std::pair<const uint8_t*, uint64_t> DoMap(int64_t request_pos,
                                            int64_t request_length) override {
    DCHECK_GE(request_pos, 0);
    DCHECK_GE(request_length, 0);

    if (request_length == 0) {
      // Returning an empty buffer without (re)mmapping, since mmap of an empty
      // file fails.
      mmap_.reset();
      return std::make_pair(static_cast<const uint8_t*>(kEmptyBuffer), 0);
    }

    // Checks if the given range is invalid. It must be verified in the caller.
    // Or probably a TOCTOU race has been happened until that check. In this
    // case, the mmap bellow will fail.
    DCHECK_LE(request_pos + request_length, file_.GetLength());

    // Maps the file.
    base::MemoryMappedFile::Region mmap_region;
    mmap_region.offset = request_pos;
    mmap_region.size = request_length;

    mmap_ = std::make_unique<base::MemoryMappedFile>();
    bool mmap_result = mmap_->Initialize(file_.Duplicate(), mmap_region);
    if (!mmap_result) {
      LOG(ERROR) << "Doing mmap failed.";
      // Returning an empty buffer without (re)mmapping, since mmap of an empty
      // file fails.
      mmap_.reset();
      return std::make_pair(nullptr, 0);
    }

    return std::make_pair(mmap_->data(), mmap_->length());
  }

 private:
  base::File file_;
  std::unique_ptr<base::MemoryMappedFile> mmap_;
};

// ============================================================================
// FileMapReaderDelegateImplMemoryReader implementation:

// This class maps and reads the logs on memory buffer. Used only in tests.
class FileMapReaderDelegateImplMemoryReader : public FileMapReaderDelegate {
 public:
  FileMapReaderDelegateImplMemoryReader(const uint8_t* buffer, uint64_t length)
      : buffer_(buffer), buffer_length_(length) {}

  int64_t GetCurrentFileSize() override { return buffer_length_; }
  FileMapReaderDelegateImplMemoryReader(
      const FileMapReaderDelegateImplMemoryReader&) = delete;
  FileMapReaderDelegateImplMemoryReader& operator=(
      const FileMapReaderDelegateImplMemoryReader&) = delete;

  std::pair<const uint8_t*, uint64_t> DoMap(int64_t request_pos,
                                            int64_t request_length) override {
    DCHECK_GE(request_pos, 0);
    DCHECK_GE(request_length, 0);

    int64_t buffer_remaining_length =
        std::max(buffer_length_ - request_pos, INT64_C(0));
    return std::make_pair(buffer_ + request_pos,
                          std::min(request_length, buffer_remaining_length));
  }

 private:
  const uint8_t* const buffer_ = nullptr;
  const int64_t buffer_length_ = 0;
};

// ============================================================================
// FileMapReader::MappedBuffer implementation:

FileMapReader::MappedBuffer::MappedBuffer(const uint8_t* buffer,
                                          uint64_t buffer_start,
                                          uint64_t buffer_length)
    : buffer_(buffer),
      buffer_start_(buffer_start),
      buffer_length_(buffer_length) {}

FileMapReader::MappedBuffer::~MappedBuffer() = default;

std::pair<const uint8_t*, uint64_t> FileMapReader::MappedBuffer::GetBuffer(
    uint64_t start_pos, uint64_t length) const {
  DCHECK(valid());
  DCHECK_LE(buffer_start_, start_pos);
  DCHECK_LE(start_pos + length, buffer_start_ + buffer_length_);

  const uint8_t* buffer = buffer_ + (start_pos - buffer_start_);
  const uint64_t buffer_remaining_length =
      buffer_length_ - (start_pos - buffer_start_);
  return std::make_pair(buffer, std::min(length, buffer_remaining_length));
}

// ============================================================================
// FileMapReader implementation:

// static
std::unique_ptr<FileMapReader> FileMapReader::CreateReader(base::File file) {
  return std::make_unique<FileMapReader>(
      std::make_unique<FileMapReaderDelegateImpl>(std::move(file)));
}

// static
uint64_t FileMapReader::GetChunkSizeInBytes() {
  return g_chunk_size_in_bytes;
}

// static
std::unique_ptr<FileMapReader>
FileMapReader::CreateFileMapReaderDelegateImplMemoryReaderForTest(
    const uint8_t* buffer, uint64_t length) {
  return std::make_unique<FileMapReader>(
      std::make_unique<FileMapReaderDelegateImplMemoryReader>(buffer, length));
}

// static
void FileMapReader::SetBlockSizesForTest(uint64_t chunk_size_in_bytes,
                                         uint32_t allocate_chunks) {
  CHECK_EQ(0, chunk_size_in_bytes % sysconf(_SC_PAGE_SIZE));
  CHECK_LE(2u, allocate_chunks);

  g_chunk_size_in_bytes = chunk_size_in_bytes;
  g_allocate_chunk_size = allocate_chunks;
}

FileMapReader::FileMapReader(std::unique_ptr<FileMapReaderDelegate> delegate)
    : delegate_(std::move(delegate)),
      file_size_(delegate_->GetCurrentFileSize()) {
  CHECK_GE(file_size_, 0);
}

FileMapReader::~FileMapReader() = default;

void FileMapReader::ApplyFileSizeExpansion() {
  const int64_t current_file_size = delegate_->GetCurrentFileSize();
  CHECK_GE(current_file_size, 0);
  if (current_file_size == file_size_)
    return;

  // We assume the log files never shrink.
  CHECK_LT(file_size_, current_file_size);

  file_size_ = current_file_size;
}

std::unique_ptr<FileMapReader::MappedBuffer> FileMapReader::MapBuffer(
    uint64_t request_pos, uint64_t request_length) {
  DCHECK_LE(request_pos + request_length, file_size_);

  // Ensure that the previous mapped buffer has already been freed.
  DCHECK(!instantiated_mapped_buffer_);

  // Reuse the previous mapped buffer if the request range is contained by the
  // previous mapped range.
  if ((buffer_ != nullptr) && (buffer_start_ <= request_pos) &&
      ((request_pos + request_length) <= (buffer_start_ + buffer_length_))) {
    return CreateMappedBuffer();
  }

  // Just check if the log files never shrink just in case. But we don't update
  // the file size here even if it's updated, for logic simplicity.
  CHECK_LE(file_size_, delegate_->GetCurrentFileSize());

  // Calculate the aligned range with enough margin.
  const std::pair<uint64_t, uint64_t> region =
      CalculateAppropriateBufferRange(request_pos, request_length, file_size_);

  const uint64_t buffer_start_pos = region.first;
  const std::pair<const uint8_t*, uint64_t> buffer =
      delegate_->DoMap(buffer_start_pos, region.second);
  buffer_ = buffer.first;
  buffer_start_ = buffer_start_pos;
  buffer_length_ = buffer.second;

  // Checks if mmap failed. It fails when the file was shrunk from the
  // previous file size check.
  if (buffer.first != nullptr) {
    // mmap succeeds.
    DCHECK_LE(buffer_start_, request_pos);
    DCHECK_LE(request_pos + request_length, buffer_start_ + buffer_length_);
  }

  return CreateMappedBuffer();
}

std::unique_ptr<FileMapReader::MappedBuffer>
FileMapReader::CreateMappedBuffer() {
  // Ensure that the previous mapped buffer has already been freed.
  // Note: The current implementation allows only one mapped buffer at the same
  // time.
  DCHECK(!instantiated_mapped_buffer_);

  // Doesn't use std::make_unique due to the private constructor.
  auto mapped_buffer = std::unique_ptr<MappedBuffer>(
      new MappedBuffer(buffer_, buffer_start_, buffer_length_));
  instantiated_mapped_buffer_ = mapped_buffer->weak_factory_.GetWeakPtr();
  return mapped_buffer;
}

}  // namespace croslog
