// Copyright 2014 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_exception_writer.h"

#include <utility>

#include "base/check_op.h"
#include "base/numerics/safe_conversions.h"
#include "minidump/minidump_context_writer.h"
#include "snapshot/exception_snapshot.h"
#include "util/file/file_writer.h"
#include "util/misc/arraysize.h"

namespace crashpad {

MinidumpExceptionWriter::MinidumpExceptionWriter()
    : MinidumpStreamWriter(), exception_(), context_(nullptr) {
}

MinidumpExceptionWriter::~MinidumpExceptionWriter() {
}

void MinidumpExceptionWriter::InitializeFromSnapshot(
    const ExceptionSnapshot* exception_snapshot,
    const MinidumpThreadIDMap& thread_id_map,
    bool allow_missing_thread_id_from_map) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(!context_);

  auto thread_id_it = thread_id_map.find(exception_snapshot->ThreadID());
  bool thread_id_missing = thread_id_it == thread_id_map.end();
  if (allow_missing_thread_id_from_map && thread_id_missing) {
    SetThreadID(static_cast<uint32_t>(exception_snapshot->ThreadID()));
  } else {
    DCHECK(!thread_id_missing);
    SetThreadID(thread_id_it->second);
  }

  SetExceptionCode(exception_snapshot->Exception());
  SetExceptionFlags(exception_snapshot->ExceptionInfo());
  SetExceptionAddress(exception_snapshot->ExceptionAddress());
  SetExceptionInformation(exception_snapshot->Codes());

  std::unique_ptr<MinidumpContextWriter> context =
      MinidumpContextWriter::CreateFromSnapshot(exception_snapshot->Context());
  SetContext(std::move(context));
}

void MinidumpExceptionWriter::SetContext(
    std::unique_ptr<MinidumpContextWriter> context) {
  DCHECK_EQ(state(), kStateMutable);

  context_ = std::move(context);
}

void MinidumpExceptionWriter::SetExceptionInformation(
    const std::vector<uint64_t>& exception_information) {
  DCHECK_EQ(state(), kStateMutable);

  const size_t parameters = exception_information.size();
  constexpr size_t kMaxParameters =
      ArraySize(exception_.ExceptionRecord.ExceptionInformation);
  CHECK_LE(parameters, kMaxParameters);

  exception_.ExceptionRecord.NumberParameters =
      base::checked_cast<uint32_t>(parameters);
  size_t parameter = 0;
  for (; parameter < parameters; ++parameter) {
    exception_.ExceptionRecord.ExceptionInformation[parameter] =
        exception_information[parameter];
  }
  for (; parameter < kMaxParameters; ++parameter) {
    exception_.ExceptionRecord.ExceptionInformation[parameter] = 0;
  }
}

bool MinidumpExceptionWriter::Freeze() {
  DCHECK_EQ(state(), kStateMutable);
  CHECK(context_);

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

  context_->RegisterLocationDescriptor(&exception_.ThreadContext);

  return true;
}

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

  return sizeof(exception_);
}

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

  std::vector<MinidumpWritable*> children;
  children.push_back(context_.get());

  return children;
}

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

  return file_writer->Write(&exception_, sizeof(exception_));
}

MinidumpStreamType MinidumpExceptionWriter::StreamType() const {
  return kMinidumpStreamTypeException;
}

}  // namespace crashpad
