// Copyright 2022 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_thread_name_list_writer.h"

#include <iterator>
#include <string>
#include <utility>

#include "base/compiler_specific.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "gtest/gtest.h"
#include "minidump/minidump_file_writer.h"
#include "minidump/minidump_system_info_writer.h"
#include "minidump/test/minidump_file_writer_test_util.h"
#include "minidump/test/minidump_string_writer_test_util.h"
#include "minidump/test/minidump_writable_test_util.h"
#include "test/gtest_death.h"
#include "util/file/string_file.h"

namespace crashpad {
namespace test {
namespace {

// This returns the MINIDUMP_THREAD_NAME_LIST stream in |thread_name_list|.
void GetThreadNameListStream(
    const std::string& file_contents,
    const MINIDUMP_THREAD_NAME_LIST** thread_name_list) {
  constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
  const uint32_t kExpectedStreams = 1;
  const size_t kThreadNameListStreamOffset =
      kDirectoryOffset + kExpectedStreams * sizeof(MINIDUMP_DIRECTORY);
  const size_t kThreadNameListOffset =
      kThreadNameListStreamOffset + sizeof(MINIDUMP_THREAD_NAME_LIST);

  ASSERT_GE(file_contents.size(), kThreadNameListOffset);

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

  ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeThreadNameList);
  EXPECT_EQ(directory[0].Location.Rva, kThreadNameListStreamOffset);

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

TEST(MinidumpThreadNameListWriter, EmptyThreadNameList) {
  MinidumpFileWriter minidump_file_writer;
  auto thread_name_list_writer =
      std::make_unique<MinidumpThreadNameListWriter>();

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

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

  ASSERT_EQ(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_THREAD_NAME_LIST));

  const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetThreadNameListStream(string_file.string(), &thread_name_list));

  EXPECT_EQ(thread_name_list->NumberOfThreadNames, 0u);
}

// The MINIDUMP_THREAD_NAMEs |expected| and |observed| are compared against
// each other using Google Test assertions.
void ExpectThreadName(const MINIDUMP_THREAD_NAME* expected,
                      const MINIDUMP_THREAD_NAME* observed,
                      const std::string& file_contents,
                      const std::string& expected_thread_name) {
  // Copy RvaOfThreadName into a local variable because
  // |MINIDUMP_THREAD_NAME::RvaOfThreadName| requires 8-byte alignment but the
  // struct itself is 4-byte algined.
  const auto rva_of_thread_name = [&observed] {
    RVA64 data = 0;
    memcpy(&data, &observed->RvaOfThreadName, sizeof(RVA64));
    return data;
  }();

  EXPECT_EQ(observed->ThreadId, expected->ThreadId);
  EXPECT_NE(rva_of_thread_name, 0u);
  const std::string observed_thread_name = base::UTF16ToUTF8(
      MinidumpStringAtRVAAsString(file_contents, rva_of_thread_name));
  EXPECT_EQ(observed_thread_name, expected_thread_name);
}

TEST(MinidumpThreadNameListWriter, OneThread) {
  MinidumpFileWriter minidump_file_writer;
  auto thread_list_writer = std::make_unique<MinidumpThreadNameListWriter>();

  constexpr uint32_t kThreadID = 0x11111111;
  const std::string kThreadName = "ariadne";

  auto thread_name_list_writer =
      std::make_unique<MinidumpThreadNameListWriter>();
  auto thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  thread_name_writer->SetThreadId(kThreadID);
  thread_name_writer->SetThreadName(kThreadName);
  thread_name_list_writer->AddThreadName(std::move(thread_name_writer));

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

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

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_THREAD_NAME_LIST) +
                1 * sizeof(MINIDUMP_THREAD_NAME));

  const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetThreadNameListStream(string_file.string(), &thread_name_list));

  EXPECT_EQ(thread_name_list->NumberOfThreadNames, 1u);

  MINIDUMP_THREAD_NAME expected = {};
  expected.ThreadId = kThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[0],
                                           string_file.string(),
                                           kThreadName));
}

TEST(MinidumpThreadNameListWriter, OneThreadWithLeadingPadding) {
  MinidumpFileWriter minidump_file_writer;

  // Add a stream before the MINIDUMP_THREAD_NAME_LIST to ensure the thread name
  // MINIDUMP_STRING requires leading padding to align to a 4-byte boundary.
  auto system_info_writer = std::make_unique<MinidumpSystemInfoWriter>();
  system_info_writer->SetCSDVersion("");
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(system_info_writer)));

  auto thread_list_writer = std::make_unique<MinidumpThreadNameListWriter>();

  constexpr uint32_t kThreadID = 0x11111111;
  const std::string kThreadName = "ariadne";

  auto thread_name_list_writer =
      std::make_unique<MinidumpThreadNameListWriter>();
  auto thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  thread_name_writer->SetThreadId(kThreadID);
  thread_name_writer->SetThreadName(kThreadName);
  thread_name_list_writer->AddThreadName(std::move(thread_name_writer));

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

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

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_THREAD_NAME_LIST) +
                1 * sizeof(MINIDUMP_THREAD_NAME));

  const uint32_t kExpectedStreams = 2;
  const MINIDUMP_DIRECTORY* directory;
  const MINIDUMP_HEADER* header =
      MinidumpHeaderAtStart(string_file.string(), &directory);
  ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, kExpectedStreams, 0));
  ASSERT_TRUE(directory);

  ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeSystemInfo);
  ASSERT_EQ(directory[1].StreamType, kMinidumpStreamTypeThreadNameList);

  const MINIDUMP_THREAD_NAME_LIST* thread_name_list =
      MinidumpWritableAtLocationDescriptor<MINIDUMP_THREAD_NAME_LIST>(
          string_file.string(), directory[1].Location);
  ASSERT_TRUE(thread_name_list);

  EXPECT_EQ(thread_name_list->NumberOfThreadNames, 1u);

  MINIDUMP_THREAD_NAME expected = {};
  expected.ThreadId = kThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[0],
                                           string_file.string(),
                                           kThreadName));
}

TEST(MinidumpThreadNameListWriter, TwoThreads_DifferentNames) {
  MinidumpFileWriter minidump_file_writer;
  auto thread_list_writer = std::make_unique<MinidumpThreadNameListWriter>();

  constexpr uint32_t kFirstThreadID = 0x11111111;
  const std::string kFirstThreadName = "ariadne";

  constexpr uint32_t kSecondThreadID = 0x22222222;
  const std::string kSecondThreadName = "theseus";

  auto thread_name_list_writer =
      std::make_unique<MinidumpThreadNameListWriter>();
  auto first_thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  first_thread_name_writer->SetThreadId(kFirstThreadID);
  first_thread_name_writer->SetThreadName(kFirstThreadName);
  thread_name_list_writer->AddThreadName(std::move(first_thread_name_writer));

  auto second_thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  second_thread_name_writer->SetThreadId(kSecondThreadID);
  second_thread_name_writer->SetThreadName(kSecondThreadName);
  thread_name_list_writer->AddThreadName(std::move(second_thread_name_writer));

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

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

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_THREAD_NAME_LIST) +
                2 * sizeof(MINIDUMP_THREAD_NAME));

  const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetThreadNameListStream(string_file.string(), &thread_name_list));

  EXPECT_EQ(thread_name_list->NumberOfThreadNames, 2u);

  MINIDUMP_THREAD_NAME expected = {};
  expected.ThreadId = kFirstThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[0],
                                           string_file.string(),
                                           kFirstThreadName));

  expected.ThreadId = kSecondThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[1],
                                           string_file.string(),
                                           kSecondThreadName));
}

TEST(MinidumpThreadNameListWriter, TwoThreads_SameNames) {
  MinidumpFileWriter minidump_file_writer;
  auto thread_list_writer = std::make_unique<MinidumpThreadNameListWriter>();

  constexpr uint32_t kFirstThreadID = 0x11111111;
  const std::string kThreadName = "ariadne";

  constexpr uint32_t kSecondThreadID = 0x22222222;

  auto thread_name_list_writer =
      std::make_unique<MinidumpThreadNameListWriter>();
  auto first_thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  first_thread_name_writer->SetThreadId(kFirstThreadID);
  first_thread_name_writer->SetThreadName(kThreadName);
  thread_name_list_writer->AddThreadName(std::move(first_thread_name_writer));

  auto second_thread_name_writer = std::make_unique<MinidumpThreadNameWriter>();
  second_thread_name_writer->SetThreadId(kSecondThreadID);
  second_thread_name_writer->SetThreadName(kThreadName);
  thread_name_list_writer->AddThreadName(std::move(second_thread_name_writer));

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

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

  ASSERT_GT(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_THREAD_NAME_LIST) +
                2 * sizeof(MINIDUMP_THREAD_NAME));

  const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetThreadNameListStream(string_file.string(), &thread_name_list));

  EXPECT_EQ(thread_name_list->NumberOfThreadNames, 2u);

  MINIDUMP_THREAD_NAME expected = {};
  expected.ThreadId = kFirstThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[0],
                                           string_file.string(),
                                           kThreadName));

  expected.ThreadId = kSecondThreadID;

  ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected,
                                           &thread_name_list->ThreadNames[1],
                                           string_file.string(),
                                           kThreadName));
}

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