// Copyright 2015 The Crashpad Authors
//
// 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_handle_writer.h"

#include <string>

#include "base/check_op.h"
#include "base/logging.h"
#include "minidump/minidump_extensions.h"
#include "util/file/file_writer.h"
#include "util/numeric/safe_assignment.h"

namespace crashpad {

MinidumpHandleDataWriter::MinidumpHandleDataWriter()
    : handle_data_stream_base_(), handle_descriptors_(), strings_() {
}

MinidumpHandleDataWriter::~MinidumpHandleDataWriter() {
  for (auto& item : strings_)
    delete item.second;
}

void MinidumpHandleDataWriter::InitializeFromSnapshot(
    const std::vector<HandleSnapshot>& handle_snapshots) {
  DCHECK_EQ(state(), kStateMutable);

  DCHECK(handle_descriptors_.empty());
  // Because we RegisterRVA() on the string writer below, we preallocate and
  // never resize the handle_descriptors_ vector.
  handle_descriptors_.resize(handle_snapshots.size());
  for (size_t i = 0; i < handle_snapshots.size(); ++i) {
    const HandleSnapshot& handle_snapshot = handle_snapshots[i];
    MINIDUMP_HANDLE_DESCRIPTOR& descriptor = handle_descriptors_[i];

    descriptor.Handle = handle_snapshot.handle;

    if (handle_snapshot.type_name.empty()) {
      descriptor.TypeNameRva = 0;
    } else {
      auto it = strings_.lower_bound(handle_snapshot.type_name);
      internal::MinidumpUTF16StringWriter* writer;
      if (it != strings_.end() && it->first == handle_snapshot.type_name) {
        writer = it->second;
      } else {
        writer = new internal::MinidumpUTF16StringWriter();
        strings_.insert(it, std::make_pair(handle_snapshot.type_name, writer));
        writer->SetUTF8(handle_snapshot.type_name);
      }
      writer->RegisterRVA(&descriptor.TypeNameRva);
    }

    descriptor.ObjectNameRva = 0;
    descriptor.Attributes = handle_snapshot.attributes;
    descriptor.GrantedAccess = handle_snapshot.granted_access;
    descriptor.HandleCount = handle_snapshot.handle_count;
    descriptor.PointerCount = handle_snapshot.pointer_count;
  }
}

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

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

  handle_data_stream_base_.SizeOfHeader = sizeof(handle_data_stream_base_);
  handle_data_stream_base_.SizeOfDescriptor = sizeof(handle_descriptors_[0]);
  const size_t handle_count = handle_descriptors_.size();
  if (!AssignIfInRange(&handle_data_stream_base_.NumberOfDescriptors,
                       handle_count)) {
    LOG(ERROR) << "handle_count " << handle_count << " out of range";
    return false;
  }
  handle_data_stream_base_.Reserved = 0;

  return true;
}

size_t MinidumpHandleDataWriter::SizeOfObject() {
  DCHECK_GE(state(), kStateFrozen);
  return sizeof(handle_data_stream_base_) +
         sizeof(handle_descriptors_[0]) * handle_descriptors_.size();
}

std::vector<internal::MinidumpWritable*> MinidumpHandleDataWriter::Children() {
  DCHECK_GE(state(), kStateFrozen);

  std::vector<MinidumpWritable*> children;
  for (const auto& pair : strings_)
    children.push_back(pair.second);
  return children;
}

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

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

  for (const auto& descriptor : handle_descriptors_) {
    iov.iov_base = &descriptor;
    iov.iov_len = sizeof(descriptor);
    iovecs.push_back(iov);
  }

  return file_writer->WriteIoVec(&iovecs);
}

MinidumpStreamType MinidumpHandleDataWriter::StreamType() const {
  return kMinidumpStreamTypeHandleData;
}

}  // namespace crashpad
