// 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 "snapshot/crashpad_types/image_annotation_reader.h"

#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>

#include "build/build_config.h"
#include "client/annotation.h"
#include "client/annotation_list.h"
#include "client/simple_string_dictionary.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "test/process_type.h"
#include "util/file/file_io.h"
#include "util/misc/as_underlying_type.h"
#include "util/misc/from_pointer_cast.h"
#include "util/process/process_memory_native.h"

#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
#include "test/linux/fake_ptrace_connection.h"
#endif

namespace crashpad {
namespace test {
namespace {

void ExpectSimpleMap(const std::map<std::string, std::string>& map,
                     const SimpleStringDictionary& expected_map) {
  EXPECT_EQ(map.size(), expected_map.GetCount());
  for (const auto& pair : map) {
    EXPECT_EQ(pair.second, expected_map.GetValueForKey(pair.first));
  }
}

void ExpectAnnotationList(const std::vector<AnnotationSnapshot>& list,
                          AnnotationList& expected_list) {
  size_t index = 0;
  for (const Annotation* expected_annotation : expected_list) {
    const AnnotationSnapshot& annotation = list[index++];
    EXPECT_EQ(annotation.name, expected_annotation->name());
    EXPECT_EQ(annotation.type, AsUnderlyingType(expected_annotation->type()));
    EXPECT_EQ(annotation.value.size(), expected_annotation->size());
    EXPECT_EQ(memcmp(annotation.value.data(),
                     expected_annotation->value(),
                     std::min(VMSize{annotation.value.size()},
                              VMSize{expected_annotation->size()})),
              0);
  }
}

void BuildTestStructures(
    std::vector<std::unique_ptr<Annotation>>* annotations_storage,
    SimpleStringDictionary* into_map,
    AnnotationList* into_annotation_list) {
  into_map->SetKeyValue("key", "value");
  into_map->SetKeyValue("key2", "value2");

  static constexpr char kAnnotationName[] = "test annotation";
  static constexpr char kAnnotationValue[] = "test annotation value";
  annotations_storage->push_back(std::make_unique<Annotation>(
      Annotation::Type::kString,
      kAnnotationName,
      reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
  annotations_storage->back()->SetSize(sizeof(kAnnotationValue));
  into_annotation_list->Add(annotations_storage->back().get());

  static constexpr char kAnnotationName2[] = "test annotation2";
  static constexpr char kAnnotationValue2[] = "test annotation value2";
  annotations_storage->push_back(std::make_unique<Annotation>(
      Annotation::Type::kString,
      kAnnotationName2,
      reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
  annotations_storage->back()->SetSize(sizeof(kAnnotationValue2));
  into_annotation_list->Add(annotations_storage->back().get());
}

void ExpectAnnotations(ProcessType process,
                       bool is_64_bit,
                       VMAddress simple_map_address,
                       VMAddress annotation_list_address) {
#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(process));
  ProcessMemoryLinux memory(&connection);
#else
  ProcessMemoryNative memory;
  ASSERT_TRUE(memory.Initialize(process));
#endif

  ProcessMemoryRange range;
  ASSERT_TRUE(range.Initialize(&memory, is_64_bit));

  SimpleStringDictionary expected_simple_map;
  std::vector<std::unique_ptr<Annotation>> storage;
  AnnotationList expected_annotations;
  BuildTestStructures(&storage, &expected_simple_map, &expected_annotations);

  ImageAnnotationReader reader(&range);

  std::map<std::string, std::string> simple_map;
  ASSERT_TRUE(reader.SimpleMap(simple_map_address, &simple_map));
  ExpectSimpleMap(simple_map, expected_simple_map);

  std::vector<AnnotationSnapshot> annotation_list;
  ASSERT_TRUE(
      reader.AnnotationsList(annotation_list_address, &annotation_list));
  ExpectAnnotationList(annotation_list, expected_annotations);
}

TEST(ImageAnnotationReader, ReadFromSelf) {
  SimpleStringDictionary map;
  std::vector<std::unique_ptr<Annotation>> storage;
  AnnotationList annotations;
  BuildTestStructures(&storage, &map, &annotations);

#if defined(ARCH_CPU_64_BITS)
  constexpr bool am_64_bit = true;
#else
  constexpr bool am_64_bit = false;
#endif

  ExpectAnnotations(GetSelfProcess(),
                    am_64_bit,
                    FromPointerCast<VMAddress>(&map),
                    FromPointerCast<VMAddress>(&annotations));
}

CRASHPAD_CHILD_TEST_MAIN(ReadAnnotationsFromChildTestMain) {
  SimpleStringDictionary map;
  std::vector<std::unique_ptr<Annotation>> storage;
  AnnotationList annotations;
  BuildTestStructures(&storage, &map, &annotations);

  VMAddress simple_map_address = FromPointerCast<VMAddress>(&map);
  VMAddress annotations_address = FromPointerCast<VMAddress>(&annotations);
  FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
  CheckedWriteFile(out, &simple_map_address, sizeof(simple_map_address));
  CheckedWriteFile(out, &annotations_address, sizeof(annotations_address));

  CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
  return 0;
}

class ReadFromChildTest : public MultiprocessExec {
 public:
  ReadFromChildTest() : MultiprocessExec() {
    SetChildTestMainFunction("ReadAnnotationsFromChildTestMain");
  }

  ~ReadFromChildTest() = default;

 private:
  void MultiprocessParent() {
#if defined(ARCH_CPU_64_BITS)
    constexpr bool am_64_bit = true;
#else
    constexpr bool am_64_bit = false;
#endif

    VMAddress simple_map_address;
    VMAddress annotations_address;
    ASSERT_TRUE(ReadFileExactly(
        ReadPipeHandle(), &simple_map_address, sizeof(simple_map_address)));
    ASSERT_TRUE(ReadFileExactly(
        ReadPipeHandle(), &annotations_address, sizeof(annotations_address)));
    ExpectAnnotations(
        ChildProcess(), am_64_bit, simple_map_address, annotations_address);
  }

  DISALLOW_COPY_AND_ASSIGN(ReadFromChildTest);
};

TEST(ImageAnnotationReader, ReadFromChild) {
  ReadFromChildTest test;
  test.Run();
}

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