// 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 <iterator>
#include <string>
#include <utility>

#include "gtest/gtest.h"
#include "minidump/minidump_context.h"
#include "minidump/minidump_context_writer.h"
#include "minidump/minidump_extensions.h"
#include "minidump/minidump_file_writer.h"
#include "minidump/test/minidump_context_test_util.h"
#include "minidump/test/minidump_file_writer_test_util.h"
#include "minidump/test/minidump_writable_test_util.h"
#include "snapshot/test/test_cpu_context.h"
#include "snapshot/test/test_exception_snapshot.h"
#include "test/gtest_death.h"
#include "util/file/string_file.h"

namespace crashpad {
namespace test {
namespace {

// This returns the MINIDUMP_EXCEPTION_STREAM stream in |exception_stream|.
void GetExceptionStream(const std::string& file_contents,
                        const MINIDUMP_EXCEPTION_STREAM** exception_stream) {
  constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
  constexpr size_t kExceptionStreamOffset =
      kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);
  constexpr size_t kContextOffset =
      kExceptionStreamOffset + sizeof(MINIDUMP_EXCEPTION_STREAM);
  constexpr size_t kFileSize = kContextOffset + sizeof(MinidumpContextX86);
  ASSERT_EQ(kFileSize, file_contents.size());

  const MINIDUMP_DIRECTORY* directory;
  const MINIDUMP_HEADER* header =
      MinidumpHeaderAtStart(file_contents, &directory);
  ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, 1, 0));

  ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeException);
  EXPECT_EQ(directory[0].Location.Rva, kExceptionStreamOffset);

  *exception_stream =
      MinidumpWritableAtLocationDescriptor<MINIDUMP_EXCEPTION_STREAM>(
          file_contents, directory[0].Location);
  ASSERT_TRUE(exception_stream);
}

// The MINIDUMP_EXCEPTION_STREAMs |expected| and |observed| are compared against
// each other using Google Test assertions. The context will be recovered from
// |file_contents| and stored in |context|.
void ExpectExceptionStream(const MINIDUMP_EXCEPTION_STREAM* expected,
                           const MINIDUMP_EXCEPTION_STREAM* observed,
                           const std::string& file_contents,
                           const MinidumpContextX86** context) {
  EXPECT_EQ(observed->ThreadId, expected->ThreadId);
  EXPECT_EQ(observed->__alignment, 0u);

  // Copy the ExceptionRecords so that their uint64_t members can be accessed
  // with the proper alignment.
  const MINIDUMP_EXCEPTION observed_exception = observed->ExceptionRecord;
  const MINIDUMP_EXCEPTION expected_exception = expected->ExceptionRecord;

  EXPECT_EQ(observed_exception.ExceptionCode, expected_exception.ExceptionCode);
  EXPECT_EQ(observed_exception.ExceptionFlags,
            expected_exception.ExceptionFlags);
  EXPECT_EQ(observed_exception.ExceptionRecord,
            expected_exception.ExceptionRecord);
  EXPECT_EQ(observed_exception.ExceptionAddress,
            expected_exception.ExceptionAddress);
  EXPECT_EQ(observed_exception.NumberParameters,
            expected_exception.NumberParameters);
  EXPECT_EQ(observed->ExceptionRecord.__unusedAlignment, 0u);
  for (size_t index = 0;
       index < std::size(observed_exception.ExceptionInformation);
       ++index) {
    EXPECT_EQ(observed_exception.ExceptionInformation[index],
              expected_exception.ExceptionInformation[index]);
  }
  *context = MinidumpWritableAtLocationDescriptor<MinidumpContextX86>(
      file_contents, observed->ThreadContext);
  ASSERT_TRUE(context);
}

TEST(MinidumpExceptionWriter, Minimal) {
  MinidumpFileWriter minidump_file_writer;
  auto exception_writer = std::make_unique<MinidumpExceptionWriter>();

  constexpr uint32_t kSeed = 100;

  auto context_x86_writer = std::make_unique<MinidumpContextX86Writer>();
  InitializeMinidumpContextX86(context_x86_writer->context(), kSeed);
  exception_writer->SetContext(std::move(context_x86_writer));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(exception_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetExceptionStream(string_file.string(), &observed_exception_stream));

  MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {};
  expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86);

  const MinidumpContextX86* observed_context = nullptr;
  ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expected_exception_stream,
                                                observed_exception_stream,
                                                string_file.string(),
                                                &observed_context));

  ASSERT_NO_FATAL_FAILURE(
      ExpectMinidumpContextX86(kSeed, observed_context, false));
}

TEST(MinidumpExceptionWriter, Standard) {
  MinidumpFileWriter minidump_file_writer;
  auto exception_writer = std::make_unique<MinidumpExceptionWriter>();

  constexpr uint32_t kSeed = 200;
  constexpr uint32_t kThreadID = 1;
  constexpr uint32_t kExceptionCode = 2;
  constexpr uint32_t kExceptionFlags = 3;
  constexpr uint32_t kExceptionRecord = 4;
  constexpr uint32_t kExceptionAddress = 5;
  constexpr uint64_t kExceptionInformation0 = 6;
  constexpr uint64_t kExceptionInformation1 = 7;
  constexpr uint64_t kExceptionInformation2 = 7;

  auto context_x86_writer = std::make_unique<MinidumpContextX86Writer>();
  InitializeMinidumpContextX86(context_x86_writer->context(), kSeed);
  exception_writer->SetContext(std::move(context_x86_writer));

  exception_writer->SetThreadID(kThreadID);
  exception_writer->SetExceptionCode(kExceptionCode);
  exception_writer->SetExceptionFlags(kExceptionFlags);
  exception_writer->SetExceptionRecord(kExceptionRecord);
  exception_writer->SetExceptionAddress(kExceptionAddress);

  // Set a lot of exception information at first, and then replace it with less.
  // This tests that the exception that is written does not contain the
  // “garbage” from the initial SetExceptionInformation() call.
  std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS,
                                              0x5a5a5a5a5a5a5a5a);
  exception_writer->SetExceptionInformation(exception_information);

  exception_information.clear();
  exception_information.push_back(kExceptionInformation0);
  exception_information.push_back(kExceptionInformation1);
  exception_information.push_back(kExceptionInformation2);
  exception_writer->SetExceptionInformation(exception_information);

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(exception_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_EXCEPTION_STREAM* observed_exception_stream = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetExceptionStream(string_file.string(), &observed_exception_stream));

  MINIDUMP_EXCEPTION_STREAM expected_exception_stream = {};
  expected_exception_stream.ThreadId = kThreadID;
  expected_exception_stream.ExceptionRecord.ExceptionCode = kExceptionCode;
  expected_exception_stream.ExceptionRecord.ExceptionFlags = kExceptionFlags;
  expected_exception_stream.ExceptionRecord.ExceptionRecord = kExceptionRecord;
  expected_exception_stream.ExceptionRecord.ExceptionAddress =
      kExceptionAddress;
  expected_exception_stream.ExceptionRecord.NumberParameters =
      static_cast<uint32_t>(exception_information.size());
  for (size_t index = 0; index < exception_information.size(); ++index) {
    expected_exception_stream.ExceptionRecord.ExceptionInformation[index] =
        exception_information[index];
  }
  expected_exception_stream.ThreadContext.DataSize = sizeof(MinidumpContextX86);

  const MinidumpContextX86* observed_context = nullptr;
  ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expected_exception_stream,
                                                observed_exception_stream,
                                                string_file.string(),
                                                &observed_context));

  ASSERT_NO_FATAL_FAILURE(
      ExpectMinidumpContextX86(kSeed, observed_context, false));
}

TEST(MinidumpExceptionWriter, InitializeFromSnapshot) {
  std::vector<uint64_t> exception_codes;
  exception_codes.push_back(0x1000000000000000);
  exception_codes.push_back(0x5555555555555555);

  MINIDUMP_EXCEPTION_STREAM expect_exception = {};

  expect_exception.ThreadId = 123;
  expect_exception.ExceptionRecord.ExceptionCode = 100;
  expect_exception.ExceptionRecord.ExceptionFlags = 1;
  expect_exception.ExceptionRecord.ExceptionAddress = 0xfedcba9876543210;
  expect_exception.ExceptionRecord.NumberParameters =
      static_cast<uint32_t>(exception_codes.size());
  for (size_t index = 0; index < exception_codes.size(); ++index) {
    expect_exception.ExceptionRecord.ExceptionInformation[index] =
        exception_codes[index];
  }
  constexpr uint64_t kThreadID = 0xaaaaaaaaaaaaaaaa;
  constexpr uint32_t kSeed = 65;

  TestExceptionSnapshot exception_snapshot;
  exception_snapshot.SetThreadID(kThreadID);
  exception_snapshot.SetException(
      expect_exception.ExceptionRecord.ExceptionCode);
  exception_snapshot.SetExceptionInfo(
      expect_exception.ExceptionRecord.ExceptionFlags);
  exception_snapshot.SetExceptionAddress(
      expect_exception.ExceptionRecord.ExceptionAddress);
  exception_snapshot.SetCodes(exception_codes);

  InitializeCPUContextX86(exception_snapshot.MutableContext(), kSeed);

  MinidumpThreadIDMap thread_id_map;
  thread_id_map[kThreadID] = expect_exception.ThreadId;

  auto exception_writer = std::make_unique<MinidumpExceptionWriter>();
  exception_writer->InitializeFromSnapshot(
      &exception_snapshot,
      thread_id_map,
      /*allow_missing_thread_id_from_map=*/false);

  MinidumpFileWriter minidump_file_writer;
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(exception_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_EXCEPTION_STREAM* exception = nullptr;
  ASSERT_NO_FATAL_FAILURE(GetExceptionStream(string_file.string(), &exception));

  const MinidumpContextX86* observed_context = nullptr;
  ASSERT_NO_FATAL_FAILURE(ExpectExceptionStream(&expect_exception,
                                                exception,
                                                string_file.string(),
                                                &observed_context));

  ASSERT_NO_FATAL_FAILURE(
      ExpectMinidumpContextX86(kSeed, observed_context, true));
}

TEST(MinidumpExceptionWriterDeathTest, NoContext) {
  MinidumpFileWriter minidump_file_writer;
  auto exception_writer = std::make_unique<MinidumpExceptionWriter>();

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(exception_writer)));

  StringFile string_file;
  ASSERT_DEATH_CHECK(minidump_file_writer.WriteEverything(&string_file),
                     "context_");
}

TEST(MinidumpExceptionWriterDeathTest, TooMuchInformation) {
  MinidumpExceptionWriter exception_writer;
  std::vector<uint64_t> exception_information(EXCEPTION_MAXIMUM_PARAMETERS + 1,
                                              0x5a5a5a5a5a5a5a5a);
  ASSERT_DEATH_CHECK(
      exception_writer.SetExceptionInformation(exception_information),
      "kMaxParameters");
}

}  // namespace
}  // namespace test
}  // namespace crashpad
