// Copyright 2017 PDFium 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 "core/fxcrt/unowned_ptr.h"

#include <functional>
#include <memory>
#include <set>
#include <utility>

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/containers/contains.h"

namespace fxcrt {
namespace {

template <typename T, typename C = std::less<T>>
class NoLinearSearchSet : public std::set<T, C> {
 public:
  typename std::set<T, C>::iterator begin() noexcept = delete;
  typename std::set<T, C>::const_iterator cbegin() const noexcept = delete;
};

class Clink {
 public:
  UnownedPtr<Clink> next_ = nullptr;
};

void DeleteDangling() {
  auto ptr2 = std::make_unique<Clink>();
  {
    auto ptr1 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
  }
}

void ResetDangling() {
  auto ptr2 = std::make_unique<Clink>();
  {
    auto ptr1 = std::make_unique<Clink>();
    ptr2->next_.Reset(ptr1.get());
  }
  ptr2->next_.Reset();
}

void AssignDangling() {
  auto ptr2 = std::make_unique<Clink>();
  {
    auto ptr1 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
  }
  ptr2->next_ = nullptr;
}

void ReleaseDangling() {
  auto ptr2 = std::make_unique<Clink>();
  {
    auto ptr1 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
  }
  ptr2->next_.Release();
}

}  // namespace

TEST(UnownedPtr, Null) {
  UnownedPtr<Clink> ptr;
  EXPECT_FALSE(ptr.Get());
}

TEST(UnownedPtr, PtrOk) {
  auto ptr1 = std::make_unique<Clink>();
  {
    auto ptr2 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
  }
}

TEST(UnownedPtr, PtrNotOk) {
#if defined(ADDRESS_SANITIZER)
  EXPECT_DEATH(DeleteDangling(), "");
#else
  DeleteDangling();
#endif
}

TEST(UnownedPtr, CopyCtor) {
  std::unique_ptr<Clink> obj = std::make_unique<Clink>();
  UnownedPtr<Clink> ptr1(obj.get());
  UnownedPtr<Clink> ptr2(ptr1);
  EXPECT_TRUE(ptr2);
  EXPECT_TRUE(ptr1);
}

TEST(UnownedPtr, CopyConversionCtor) {
  std::unique_ptr<Clink> obj = std::make_unique<Clink>();
  UnownedPtr<Clink> ptr1(obj.get());
  UnownedPtr<const Clink> ptr2(ptr1);
  EXPECT_TRUE(ptr2);
  EXPECT_TRUE(ptr1);
}

TEST(UnownedPtr, ResetOk) {
  auto ptr1 = std::make_unique<Clink>();
  {
    auto ptr2 = std::make_unique<Clink>();
    ptr2->next_.Reset(ptr1.get());
    ptr2->next_.Reset(nullptr);
  }
}

TEST(UnownedPtr, ResetNotOk) {
#if defined(ADDRESS_SANITIZER)
  EXPECT_DEATH(ResetDangling(), "");
#else
  ResetDangling();
#endif
}

TEST(UnownedPtr, AssignOk) {
  auto ptr1 = std::make_unique<Clink>();
  {
    auto ptr2 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
    ptr2->next_ = nullptr;
  }
}

TEST(UnownedPtr, AssignNotOk) {
#if defined(ADDRESS_SANITIZER)
  EXPECT_DEATH(AssignDangling(), "");
#else
  AssignDangling();
#endif
}

TEST(UnownedPtr, ReleaseOk) {
  auto ptr2 = std::make_unique<Clink>();
  {
    auto ptr1 = std::make_unique<Clink>();
    ptr2->next_ = ptr1.get();
    ptr2->next_.Release();
  }
}

TEST(UnownedPtr, MoveCtorOk) {
  UnownedPtr<Clink> outer;
  {
    auto owned = std::make_unique<Clink>();
    outer = owned.get();
    UnownedPtr<Clink> inner(std::move(outer));
    EXPECT_FALSE(outer.Get());
    EXPECT_EQ(owned.get(), inner.Get());
  }
}

TEST(UnownedPtr, MoveConversionCtorOk) {
  UnownedPtr<Clink> outer;
  {
    auto owned = std::make_unique<Clink>();
    outer = owned.get();
    UnownedPtr<const Clink> inner(std::move(outer));
    EXPECT_FALSE(outer.Get());
  }
}

TEST(UnownedPtr, MoveConversionAssignOk) {
  UnownedPtr<Clink> outer;
  {
    auto owned = std::make_unique<Clink>();
    outer = owned.get();
    // TODO(tsepez): disambiguate ctors and actually const-convert.
    // UnownedPtr<const Clink> inner;
    UnownedPtr<Clink> inner;
    inner = std::move(outer);
    EXPECT_FALSE(outer);
    EXPECT_EQ(owned.get(), inner.Get());
  }
}

TEST(UnownedPtr, ReleaseNotOk) {
#if defined(ADDRESS_SANITIZER)
  EXPECT_DEATH(ReleaseDangling(), "");
#else
  ReleaseDangling();
#endif
}

TEST(UnownedPtr, OperatorEQ) {
  int foo;
  UnownedPtr<int> ptr1;
  EXPECT_TRUE(ptr1 == ptr1);

  UnownedPtr<int> ptr2;
  EXPECT_TRUE(ptr1 == ptr2);

  UnownedPtr<int> ptr3(&foo);
  EXPECT_TRUE(&foo == ptr3);
  EXPECT_TRUE(ptr3 == &foo);
  EXPECT_FALSE(ptr1 == ptr3);

  ptr1 = &foo;
  EXPECT_TRUE(ptr1 == ptr3);
}

TEST(UnownedPtr, OperatorNE) {
  int foo;
  UnownedPtr<int> ptr1;
  EXPECT_FALSE(ptr1 != ptr1);

  UnownedPtr<int> ptr2;
  EXPECT_FALSE(ptr1 != ptr2);

  UnownedPtr<int> ptr3(&foo);
  EXPECT_FALSE(&foo != ptr3);
  EXPECT_FALSE(ptr3 != &foo);
  EXPECT_TRUE(ptr1 != ptr3);

  ptr1 = &foo;
  EXPECT_FALSE(ptr1 != ptr3);
}

TEST(UnownedPtr, OperatorLT) {
  int foos[2];
  UnownedPtr<int> ptr1(&foos[0]);
  UnownedPtr<int> ptr2(&foos[1]);

  EXPECT_FALSE(ptr1 < ptr1);
  EXPECT_TRUE(ptr1 < ptr2);
  EXPECT_FALSE(ptr2 < ptr1);
}

TEST(UnownedPtr, TransparentCompare) {
  int foos[2];
  UnownedPtr<int> ptr1(&foos[0]);
  UnownedPtr<int> ptr2(&foos[1]);
  NoLinearSearchSet<UnownedPtr<int>, std::less<>> holder;
  holder.insert(ptr1);
  EXPECT_NE(holder.end(), holder.find(&foos[0]));
  EXPECT_EQ(holder.end(), holder.find(&foos[1]));
  EXPECT_TRUE(pdfium::Contains(holder, &foos[0]));
  EXPECT_FALSE(pdfium::Contains(holder, &foos[1]));
}

}  // namespace fxcrt
