// 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) {
  DCHECK_EQ(state(), kStateMutable);
  DCHECK(!context_);

  auto thread_id_it = thread_id_map.find(exception_snapshot->ThreadID());
  DCHECK(thread_id_it != thread_id_map.end());
  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
