// 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_memory_info_writer.h"

#include <memory>
#include <string>
#include <utility>

#include "gtest/gtest.h"
#include "minidump/minidump_file_writer.h"
#include "minidump/test/minidump_file_writer_test_util.h"
#include "minidump/test/minidump_writable_test_util.h"
#include "snapshot/test/test_memory_map_region_snapshot.h"
#include "util/file/string_file.h"

namespace crashpad {
namespace test {
namespace {

// The memory info list is expected to be the only stream.
void GetMemoryInfoListStream(
    const std::string& file_contents,
    const MINIDUMP_MEMORY_INFO_LIST** memory_info_list) {
  constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
  constexpr size_t kMemoryInfoListStreamOffset =
      kDirectoryOffset + sizeof(MINIDUMP_DIRECTORY);

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

  constexpr size_t kDirectoryIndex = 0;

  ASSERT_EQ(directory[kDirectoryIndex].StreamType,
            kMinidumpStreamTypeMemoryInfoList);
  EXPECT_EQ(directory[kDirectoryIndex].Location.Rva,
            kMemoryInfoListStreamOffset);

  *memory_info_list =
      MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_INFO_LIST>(
          file_contents, directory[kDirectoryIndex].Location);
  ASSERT_TRUE(*memory_info_list);
}

TEST(MinidumpMemoryInfoWriter, Empty) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_info_list_writer =
      std::make_unique<MinidumpMemoryInfoListWriter>();
  ASSERT_TRUE(
      minidump_file_writer.AddStream(std::move(memory_info_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_MEMORY_INFO_LIST));

  const MINIDUMP_MEMORY_INFO_LIST* memory_info_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryInfoListStream(string_file.string(), &memory_info_list));

  uint64_t number_of_entries;
  memcpy(&number_of_entries,
         &memory_info_list->NumberOfEntries,
         sizeof(number_of_entries));
  EXPECT_EQ(number_of_entries, 0u);
}

TEST(MinidumpMemoryInfoWriter, OneRegion) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_info_list_writer =
      std::make_unique<MinidumpMemoryInfoListWriter>();

  auto memory_map_region = std::make_unique<TestMemoryMapRegionSnapshot>();

  MINIDUMP_MEMORY_INFO mmi;
  mmi.BaseAddress = 0x12340000;
  mmi.AllocationBase = 0x12000000;
  mmi.AllocationProtect = PAGE_READWRITE;
  mmi.__alignment1 = 0;
  mmi.RegionSize = 0x6000;
  mmi.State = MEM_COMMIT;
  mmi.Protect = PAGE_NOACCESS;
  mmi.Type = MEM_PRIVATE;
  mmi.__alignment2 = 0;
  memory_map_region->SetMindumpMemoryInfo(mmi);

  std::vector<const MemoryMapRegionSnapshot*> memory_map;
  memory_map.push_back(memory_map_region.get());
  memory_info_list_writer->InitializeFromSnapshot(memory_map);

  ASSERT_TRUE(
      minidump_file_writer.AddStream(std::move(memory_info_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_MEMORY_INFO_LIST) +
                sizeof(MINIDUMP_MEMORY_INFO));

  const MINIDUMP_MEMORY_INFO_LIST* memory_info_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryInfoListStream(string_file.string(), &memory_info_list));

  uint64_t number_of_entries;
  memcpy(&number_of_entries,
         &memory_info_list->NumberOfEntries,
         sizeof(number_of_entries));
  EXPECT_EQ(number_of_entries, 1u);

  MINIDUMP_MEMORY_INFO memory_info;
  memcpy(&memory_info, &memory_info_list[1], sizeof(memory_info));
  EXPECT_EQ(memory_info.BaseAddress, mmi.BaseAddress);
  EXPECT_EQ(memory_info.AllocationBase, mmi.AllocationBase);
  EXPECT_EQ(memory_info.AllocationProtect, mmi.AllocationProtect);
  EXPECT_EQ(memory_info.RegionSize, mmi.RegionSize);
  EXPECT_EQ(memory_info.State, mmi.State);
  EXPECT_EQ(memory_info.Protect, mmi.Protect);
  EXPECT_EQ(memory_info.Type, mmi.Type);
}

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