// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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_annotation_writer.h"

#include <memory>

#include "base/cxx17_backports.h"
#include "gtest/gtest.h"
#include "minidump/minidump_extensions.h"
#include "minidump/test/minidump_byte_array_writer_test_util.h"
#include "minidump/test/minidump_string_writer_test_util.h"
#include "minidump/test/minidump_writable_test_util.h"
#include "util/file/string_file.h"

namespace crashpad {
namespace test {
namespace {

const MinidumpAnnotationList* MinidumpAnnotationListAtStart(
    const std::string& file_contents,
    uint32_t count) {
  MINIDUMP_LOCATION_DESCRIPTOR location_descriptor;
  location_descriptor.DataSize = static_cast<uint32_t>(
      sizeof(MinidumpAnnotationList) + count * sizeof(MinidumpAnnotation));
  location_descriptor.Rva = 0;
  return MinidumpWritableAtLocationDescriptor<MinidumpAnnotationList>(
      file_contents, location_descriptor);
}

TEST(MinidumpAnnotationWriter, EmptyList) {
  StringFile string_file;

  MinidumpAnnotationListWriter list_writer;

  EXPECT_FALSE(list_writer.IsUseful());

  EXPECT_TRUE(list_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(), sizeof(MinidumpAnnotationList));

  auto* list = MinidumpAnnotationListAtStart(string_file.string(), 0);
  ASSERT_TRUE(list);
  EXPECT_EQ(list->count, 0u);
}

TEST(MinidumpAnnotationWriter, OneItem) {
  StringFile string_file;

  const char kName[] = "name";
  const uint16_t kType = 0xFFFF;
  const std::vector<uint8_t> kValue{'v', 'a', 'l', 'u', 'e', '\0'};

  auto annotation_writer = std::make_unique<MinidumpAnnotationWriter>();
  annotation_writer->InitializeWithData(kName, kType, kValue);

  MinidumpAnnotationListWriter list_writer;
  list_writer.AddObject(std::move(annotation_writer));

  EXPECT_TRUE(list_writer.IsUseful());

  EXPECT_TRUE(list_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(),
            sizeof(MinidumpAnnotationList) + sizeof(MinidumpAnnotation) +
                sizeof(MinidumpUTF8String) + sizeof(kName) +
                sizeof(MinidumpByteArray) + kValue.size() +
                3);  // 3 for padding.

  auto* list = MinidumpAnnotationListAtStart(string_file.string(), 1);
  ASSERT_TRUE(list);
  EXPECT_EQ(list->count, 1u);
  EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(),
                                            list->objects[0].name),
            kName);
  EXPECT_EQ(list->objects[0].type, kType);
  EXPECT_EQ(list->objects[0].reserved, 0u);
  EXPECT_EQ(

      MinidumpByteArrayAtRVA(string_file.string(), list->objects[0].value),
      kValue);
}

TEST(MinidumpAnnotationWriter, ThreeItems) {
  StringFile string_file;

  const char* kNames[] = {
      "~~FIRST~~", " second + ", "3",
  };
  const uint16_t kTypes[] = {
      0x1, 0xABCD, 0x42,
  };
  const std::vector<uint8_t> kValues[] = {
      {'\0'}, {0xB0, 0xA0, 0xD0, 0xD0, 0xD0}, {'T'},
  };

  MinidumpAnnotationListWriter list_writer;

  for (size_t i = 0; i < base::size(kNames); ++i) {
    auto annotation = std::make_unique<MinidumpAnnotationWriter>();
    annotation->InitializeWithData(kNames[i], kTypes[i], kValues[i]);
    list_writer.AddObject(std::move(annotation));
  }

  EXPECT_TRUE(list_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(),
            sizeof(MinidumpAnnotationList) + 3 * sizeof(MinidumpAnnotation) +
                3 * sizeof(MinidumpUTF8String) + 3 * sizeof(MinidumpByteArray) +
                strlen(kNames[0]) + 1 + kValues[0].size() + 2 +
                strlen(kNames[1]) + 1 + 3 + kValues[1].size() + 1 +
                strlen(kNames[2]) + 1 + 3 + kValues[2].size() + 2);

  auto* list = MinidumpAnnotationListAtStart(string_file.string(), 3);
  ASSERT_TRUE(list);
  EXPECT_EQ(list->count, 3u);

  for (size_t i = 0; i < 3; ++i) {
    EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(),
                                              list->objects[i].name),
              kNames[i]);
    EXPECT_EQ(list->objects[i].type, kTypes[i]);
    EXPECT_EQ(list->objects[i].reserved, 0u);
    EXPECT_EQ(

        MinidumpByteArrayAtRVA(string_file.string(), list->objects[i].value),
        kValues[i]);
  }
}

TEST(MinidumpAnnotationWriter, DuplicateNames) {
  StringFile string_file;

  const char kName[] = "@@name!";
  const uint16_t kType = 0x1;
  const std::vector<uint8_t> kValue1{'r', 'e', 'd', '\0'};
  const std::vector<uint8_t> kValue2{'m', 'a', 'g', 'e', 'n', 't', 'a', '\0'};

  MinidumpAnnotationListWriter list_writer;

  auto annotation = std::make_unique<MinidumpAnnotationWriter>();
  annotation->InitializeWithData(kName, kType, kValue1);
  list_writer.AddObject(std::move(annotation));

  annotation = std::make_unique<MinidumpAnnotationWriter>();
  annotation->InitializeWithData(kName, kType, kValue2);
  list_writer.AddObject(std::move(annotation));

  EXPECT_TRUE(list_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(),
            sizeof(MinidumpAnnotationList) + 2 * sizeof(MinidumpAnnotation) +
                2 * sizeof(MinidumpUTF8String) + 2 * sizeof(MinidumpByteArray) +
                2 * sizeof(kName) + kValue1.size() + kValue2.size());

  auto* list = MinidumpAnnotationListAtStart(string_file.string(), 2);
  ASSERT_TRUE(list);
  EXPECT_EQ(list->count, 2u);

  EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(),
                                            list->objects[0].name),
            kName);
  EXPECT_EQ(list->objects[0].type, kType);
  EXPECT_EQ(

      MinidumpByteArrayAtRVA(string_file.string(), list->objects[0].value),
      kValue1);

  EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(),
                                            list->objects[1].name),
            kName);
  EXPECT_EQ(list->objects[1].type, kType);
  EXPECT_EQ(

      MinidumpByteArrayAtRVA(string_file.string(), list->objects[1].value),
      kValue2);
}

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