// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 "minidump/minidump_memory_writer.h"

#include <algorithm>
#include <iterator>
#include <utility>

#include "base/auto_reset.h"
#include "base/logging.h"
#include "util/file/file_writer.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {

SnapshotMinidumpMemoryWriter::SnapshotMinidumpMemoryWriter(
    const MemorySnapshot* memory_snapshot)
    : internal::MinidumpWritable(),
      MemorySnapshot::Delegate(),
      memory_descriptor_(),
      registered_memory_descriptors_(),
      memory_snapshot_(memory_snapshot),
      file_writer_(nullptr) {}

SnapshotMinidumpMemoryWriter::~SnapshotMinidumpMemoryWriter() {}

bool SnapshotMinidumpMemoryWriter::MemorySnapshotDelegateRead(void* data,
                                                              size_t size) {
  DCHECK_EQ(state(), kStateWritable);
  DCHECK_EQ(size, UnderlyingSnapshot()->Size());
  return file_writer_->Write(data, size);
}

bool SnapshotMinidumpMemoryWriter::WriteObject(
    FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);
  DCHECK(!file_writer_);

  base::AutoReset<FileWriterInterface*> file_writer_reset(&file_writer_,
                                                          file_writer);

  // This will result in MemorySnapshotDelegateRead() being called.
  if (!memory_snapshot_->Read(this)) {
    // If the Read() fails (perhaps because the process' memory map has changed
    // since it the range was captured), write an empty block of memory. It
    // would be nice to instead not include this memory, but at this point in
    // the writing process, it would be difficult to amend the minidump's
    // structure. See https://crashpad.chromium.org/234 for background.
    std::vector<uint8_t> empty(memory_snapshot_->Size(), 0xfe);
    MemorySnapshotDelegateRead(empty.data(), empty.size());
  }

  return true;
}

const MINIDUMP_MEMORY_DESCRIPTOR*
SnapshotMinidumpMemoryWriter::MinidumpMemoryDescriptor() const {
  DCHECK_EQ(state(), kStateWritable);

  return &memory_descriptor_;
}

void SnapshotMinidumpMemoryWriter::RegisterMemoryDescriptor(
    MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor) {
  DCHECK_LE(state(), kStateFrozen);

  registered_memory_descriptors_.push_back(memory_descriptor);
  RegisterLocationDescriptor(&memory_descriptor->Memory);
}

bool SnapshotMinidumpMemoryWriter::Freeze() {
  DCHECK_EQ(state(), kStateMutable);

  if (!MinidumpWritable::Freeze()) {
    return false;
  }

  RegisterMemoryDescriptor(&memory_descriptor_);

  return true;
}

size_t SnapshotMinidumpMemoryWriter::Alignment() {
  DCHECK_GE(state(), kStateFrozen);

  return 16;
}

size_t SnapshotMinidumpMemoryWriter::SizeOfObject() {
  DCHECK_GE(state(), kStateFrozen);

  return UnderlyingSnapshot()->Size();
}

bool SnapshotMinidumpMemoryWriter::WillWriteAtOffsetImpl(FileOffset offset) {
  DCHECK_EQ(state(), kStateFrozen);

  // There will always be at least one registered descriptor, the one for this
  // object’s own memory_descriptor_ field.
  DCHECK_GE(registered_memory_descriptors_.size(), 1u);

  uint64_t base_address = UnderlyingSnapshot()->Address();
  decltype(registered_memory_descriptors_[0]->StartOfMemoryRange) local_address;
  if (!AssignIfInRange(&local_address, base_address)) {
    LOG(ERROR) << "base_address " << base_address << " out of range";
    return false;
  }

  for (MINIDUMP_MEMORY_DESCRIPTOR* memory_descriptor :
           registered_memory_descriptors_) {
    memory_descriptor->StartOfMemoryRange = local_address;
  }

  return MinidumpWritable::WillWriteAtOffsetImpl(offset);
}

internal::MinidumpWritable::Phase SnapshotMinidumpMemoryWriter::WritePhase() {
  // Memory dumps are large and are unlikely to be consumed in their entirety.
  // Data accesses are expected to be sparse and sporadic, and are expected to
  // occur after all of the other structural and informational data from the
  // minidump file has been read. Put memory dumps at the end of the minidump
  // file to improve spatial locality.
  return kPhaseLate;
}

MinidumpMemoryListWriter::MinidumpMemoryListWriter()
    : MinidumpStreamWriter(),
      non_owned_memory_writers_(),
      children_(),
      snapshots_created_during_merge_(),
      all_memory_writers_(),
      memory_list_base_() {}

MinidumpMemoryListWriter::~MinidumpMemoryListWriter() {
}

void MinidumpMemoryListWriter::AddFromSnapshot(
    const std::vector<const MemorySnapshot*>& memory_snapshots) {
  DCHECK_EQ(state(), kStateMutable);

  for (const MemorySnapshot* memory_snapshot : memory_snapshots) {
    std::unique_ptr<SnapshotMinidumpMemoryWriter> memory(
        new SnapshotMinidumpMemoryWriter(memory_snapshot));
    AddMemory(std::move(memory));
  }
}

void MinidumpMemoryListWriter::AddMemory(
    std::unique_ptr<SnapshotMinidumpMemoryWriter> memory_writer) {
  DCHECK_EQ(state(), kStateMutable);

  children_.push_back(std::move(memory_writer));
}

void MinidumpMemoryListWriter::AddNonOwnedMemory(
    SnapshotMinidumpMemoryWriter* memory_writer) {
  DCHECK_EQ(state(), kStateMutable);

  non_owned_memory_writers_.push_back(memory_writer);
}

void MinidumpMemoryListWriter::CoalesceOwnedMemory() {
  if (children_.empty())
    return;

  DropRangesThatOverlapNonOwned();

  std::sort(children_.begin(),
            children_.end(),
            [](const std::unique_ptr<SnapshotMinidumpMemoryWriter>& a_ptr,
               const std::unique_ptr<SnapshotMinidumpMemoryWriter>& b_ptr) {
              const MemorySnapshot* a = a_ptr->UnderlyingSnapshot();
              const MemorySnapshot* b = b_ptr->UnderlyingSnapshot();
              if (a->Address() == b->Address()) {
                return a->Size() < b->Size();
              }
              return a->Address() < b->Address();
            });

  // Remove any empty ranges.
  children_.erase(
      std::remove_if(
          children_.begin(),
          children_.end(),
          [](const std::unique_ptr<SnapshotMinidumpMemoryWriter>& snapshot) {
            return snapshot->UnderlyingSnapshot()->Size() == 0;
          }),
      children_.end());

  std::vector<std::unique_ptr<SnapshotMinidumpMemoryWriter>> all_merged;
  all_merged.push_back(std::move(children_.front()));
  for (size_t i = 1; i < children_.size(); ++i) {
    SnapshotMinidumpMemoryWriter* top = all_merged.back().get();
    auto& child = children_[i];
    if (!DetermineMergedRange(
            child->UnderlyingSnapshot(), top->UnderlyingSnapshot(), nullptr)) {
      // If it doesn't overlap with the current range, push it.
      all_merged.push_back(std::move(child));
    } else {
      // Otherwise, merge and update the current element.
      std::unique_ptr<const MemorySnapshot> merged(
          top->UnderlyingSnapshot()->MergeWithOtherSnapshot(
              child->UnderlyingSnapshot()));
      top->SetSnapshot(merged.get());
      snapshots_created_during_merge_.push_back(std::move(merged));
    }
  }
  std::swap(children_, all_merged);
}

bool MinidumpMemoryListWriter::Freeze() {
  DCHECK_EQ(state(), kStateMutable);

  CoalesceOwnedMemory();

  std::copy(non_owned_memory_writers_.begin(),
            non_owned_memory_writers_.end(),
            std::back_inserter(all_memory_writers_));
  for (const auto& ptr : children_)
    all_memory_writers_.push_back(ptr.get());

  if (!MinidumpStreamWriter::Freeze()) {
    return false;
  }

  size_t memory_region_count = all_memory_writers_.size();
  CHECK_LE(children_.size(), memory_region_count);

  if (!AssignIfInRange(&memory_list_base_.NumberOfMemoryRanges,
                       memory_region_count)) {
    LOG(ERROR) << "memory_region_count " << memory_region_count
               << " out of range";
    return false;
  }

  return true;
}

size_t MinidumpMemoryListWriter::SizeOfObject() {
  DCHECK_GE(state(), kStateFrozen);
  DCHECK_LE(children_.size(), all_memory_writers_.size());

  return sizeof(memory_list_base_) +
         all_memory_writers_.size() * sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
}

std::vector<internal::MinidumpWritable*> MinidumpMemoryListWriter::Children() {
  DCHECK_GE(state(), kStateFrozen);
  DCHECK_LE(children_.size(), all_memory_writers_.size());

  std::vector<MinidumpWritable*> children;
  for (const auto& child : children_) {
    children.push_back(child.get());
  }

  return children;
}

bool MinidumpMemoryListWriter::WriteObject(FileWriterInterface* file_writer) {
  DCHECK_EQ(state(), kStateWritable);

  WritableIoVec iov;
  iov.iov_base = &memory_list_base_;
  iov.iov_len = sizeof(memory_list_base_);
  std::vector<WritableIoVec> iovecs(1, iov);

  for (const SnapshotMinidumpMemoryWriter* memory_writer :
       all_memory_writers_) {
    iov.iov_base = memory_writer->MinidumpMemoryDescriptor();
    iov.iov_len = sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
    iovecs.push_back(iov);
  }

  return file_writer->WriteIoVec(&iovecs);
}

MinidumpStreamType MinidumpMemoryListWriter::StreamType() const {
  return kMinidumpStreamTypeMemoryList;
}

void MinidumpMemoryListWriter::DropRangesThatOverlapNonOwned() {
  std::vector<std::unique_ptr<SnapshotMinidumpMemoryWriter>> non_overlapping;
  non_overlapping.reserve(children_.size());
  for (auto& child_ptr : children_) {
    bool overlaps = false;
    for (const auto* non_owned : non_owned_memory_writers_) {
      if (DetermineMergedRange(child_ptr->UnderlyingSnapshot(),
                               non_owned->UnderlyingSnapshot(),
                               nullptr)) {
        overlaps = true;
        break;
      }
    }
    if (!overlaps)
      non_overlapping.push_back(std::move(child_ptr));
  }
  std::swap(children_, non_overlapping);
}

}  // namespace crashpad
