// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/fidl/llcpp/unowned_ptr.h>

#include <unordered_set>

#include <gtest/gtest.h>

TEST(UnownedPtr, Constructor) {
  int32_t val = 1;
  fidl::unowned_ptr_t<int32_t> a(&val);
  EXPECT_EQ(a.get(), &val);
  fidl::unowned_ptr_t<int32_t> b(a);
  EXPECT_EQ(a.get(), &val);
  EXPECT_EQ(b.get(), &val);
  fidl::unowned_ptr_t<int32_t> c(nullptr);
  EXPECT_EQ(c.get(), nullptr);
}

TEST(UnownedPtr, VoidConstructor) {
  int32_t val = 1;
  void* vptr = &val;
  fidl::unowned_ptr_t<void> a(vptr);
  EXPECT_EQ(a.get(), vptr);
  fidl::unowned_ptr_t<void> b(a);
  EXPECT_EQ(a.get(), vptr);
  EXPECT_EQ(b.get(), vptr);
  fidl::unowned_ptr_t<void> c(nullptr);
  EXPECT_EQ(c.get(), nullptr);
}

TEST(UnownedPtr, Destructor) {
  struct DestructableObject {
    ~DestructableObject() { *destructor_called = true; }
    bool* destructor_called;
  };

  bool destructor_called = false;
  DestructableObject x{.destructor_called = &destructor_called};
  { fidl::unowned_ptr_t<DestructableObject> ptr(&x); }
  EXPECT_FALSE(destructor_called);
}

TEST(UnownedPtr, Assignment) {
  int32_t val1 = 1, val2 = 2;
  fidl::unowned_ptr_t<int32_t> a(&val1);
  EXPECT_EQ(a.get(), &val1);
  fidl::unowned_ptr_t<int32_t> b(&val2);
  EXPECT_EQ(b.get(), &val2);
  b = a;
  EXPECT_EQ(a.get(), &val1);
  EXPECT_EQ(b.get(), &val1);
  b = std::move(a);
  EXPECT_EQ(a.get(), &val1);
  EXPECT_EQ(b.get(), &val1);
  b = &val2;
  EXPECT_EQ(b.get(), &val2);
  b = nullptr;
  EXPECT_EQ(b.get(), nullptr);
}

TEST(UnownedPtr, VoidAssignment) {
  int32_t val1 = 1, val2 = 2;
  void* vptr1 = &val1;
  void* vptr2 = &val2;
  fidl::unowned_ptr_t<void> a(vptr1);
  EXPECT_EQ(a.get(), vptr1);
  fidl::unowned_ptr_t<void> b(vptr2);
  EXPECT_EQ(b.get(), vptr2);
  b = a;
  EXPECT_EQ(a.get(), vptr1);
  EXPECT_EQ(b.get(), vptr1);
  b = vptr2;
  EXPECT_EQ(b.get(), vptr2);
  b = nullptr;
  EXPECT_EQ(b.get(), nullptr);
}

TEST(UnownedPtr, OperatorBool) {
  fidl::unowned_ptr_t<int32_t> default_ptr;
  EXPECT_FALSE(default_ptr);
  int32_t val = 1;
  fidl::unowned_ptr_t<int32_t> ptr(&val);
  EXPECT_TRUE(ptr);
  ptr = nullptr;
  EXPECT_FALSE(ptr);
  ptr = reinterpret_cast<int32_t*>(0);
  EXPECT_FALSE(ptr);
}

TEST(UnownedPtr, Dereference) {
  struct TestStruct {
    int a;
  };
  TestStruct example{.a = 1};
  fidl::unowned_ptr_t<TestStruct> example_ptr(&example);
  EXPECT_EQ((*example_ptr).a, 1);
  EXPECT_EQ(example_ptr->a, 1);
  *example_ptr = TestStruct{.a = 2};
  EXPECT_EQ(example_ptr->a, 2);
}

TEST(UnownedPtr, Indexing) {
  int32_t arr[3] = {1, 2, 3};
  fidl::unowned_ptr_t<int32_t> ptr(arr);
  EXPECT_EQ(ptr[1], 2);
  ptr[0] = 4;
  EXPECT_EQ(ptr[0], 4);
}

TEST(UnownedPtr, Swap) {
  int32_t x, y;
  fidl::unowned_ptr_t<int32_t> x_ptr(&x);
  fidl::unowned_ptr_t<int32_t> y_ptr(&y);
  std::swap(x_ptr, y_ptr);
  EXPECT_EQ(x_ptr.get(), &y);
  EXPECT_EQ(y_ptr.get(), &x);
}

TEST(UnownedPtr, Hashing) {
  int32_t val;
  fidl::unowned_ptr_t<int32_t> ptr(&val);
  EXPECT_EQ(std::hash<fidl::unowned_ptr_t<int32_t>>{}(ptr), std::hash<int32_t*>{}(&val));

  // Ensure that hashing is correctly implemented so unordered_set can be used.
  std::unordered_set<fidl::unowned_ptr_t<int32_t>> set;
  set.insert(ptr);
}

TEST(UnownedPtr, Comparison) {
  int32_t* lower_ptr = reinterpret_cast<int32_t*>(1);
  int32_t* upper_ptr = reinterpret_cast<int32_t*>(2);
  fidl::unowned_ptr_t<int32_t> lower(lower_ptr);
  fidl::unowned_ptr_t<int32_t> lower2(lower_ptr);
  fidl::unowned_ptr_t<int32_t> upper(upper_ptr);

  EXPECT_TRUE(lower == lower2);
  EXPECT_FALSE(lower == upper);
  EXPECT_TRUE(lower != upper);
  EXPECT_FALSE(lower != lower2);
  EXPECT_TRUE(lower < upper);
  EXPECT_FALSE(lower < lower);
  EXPECT_FALSE(upper < lower);
  EXPECT_TRUE(lower <= upper);
  EXPECT_TRUE(lower <= lower);
  EXPECT_FALSE(upper <= lower);
  EXPECT_TRUE(upper > lower);
  EXPECT_FALSE(upper > upper);
  EXPECT_FALSE(lower > upper);
  EXPECT_TRUE(upper >= lower);
  EXPECT_TRUE(upper >= upper);
  EXPECT_FALSE(lower >= upper);

  EXPECT_FALSE(lower == nullptr);
  EXPECT_FALSE(nullptr == lower);
  EXPECT_TRUE(lower != nullptr);
  EXPECT_TRUE(nullptr != lower);

  // Ensure that comparison is correctly implemented so set can be used.
  std::set<fidl::unowned_ptr_t<int32_t>> set;
  set.insert(lower);
}

TEST(UnownedPtr, Const) {
  int32_t val = 1;
  fidl::unowned_ptr_t<int32_t> ptr(&val);
  fidl::unowned_ptr_t<const int32_t> const_ptr(ptr);
  EXPECT_EQ(*const_ptr, val);
}

TEST(UnownedPtr, Casting) {
  class Base {};
  class Derived : public Base {};
  Derived d;
  fidl::unowned_ptr_t<Derived> d_ptr(&d);
  EXPECT_EQ(static_cast<fidl::unowned_ptr_t<Base>>(d_ptr).get(), static_cast<Base*>(&d));

  auto vptr = static_cast<fidl::unowned_ptr_t<void>>(d_ptr);
  EXPECT_EQ(vptr, fidl::unowned_ptr_t<void>(&d));

  auto d_ptr2 = static_cast<fidl::unowned_ptr_t<Derived>>(vptr);
  EXPECT_EQ(d_ptr2, d_ptr);
}
