// Copyright 2019 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <lib/unittest/unittest.h>

#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <ktl/move.h>
#include <object/dispatcher.h>
#include <object/event_pair_dispatcher.h>

#include "object/handle.h"

namespace {

// A Dispatcher-like class that tracks the number of calls to on_zero_handles()
// for testing purposes.
//
// This base class is available so that we can test that KernelHandle can
// properly upcast child->base RefPtrs.
class FakeDispatcherBase : public fbl::RefCounted<FakeDispatcherBase> {
 public:
  virtual ~FakeDispatcherBase() = default;

  int on_zero_handles_calls() const { return on_zero_handles_calls_; }
  void on_zero_handles() { on_zero_handles_calls_++; }

 protected:
  FakeDispatcherBase() = default;

 private:
  int on_zero_handles_calls_ = 0;
};

class FakeDispatcher : public FakeDispatcherBase {
 public:
  static fbl::RefPtr<FakeDispatcher> Create() {
    fbl::AllocChecker ac;
    auto dispatcher = fbl::AdoptRef(new (&ac) FakeDispatcher());
    if (!ac.check()) {
      unittest_printf("Failed to allocate FakeDispatcher\n");
      return nullptr;
    }
    return dispatcher;
  }

  ~FakeDispatcher() override = default;

 private:
  FakeDispatcher() = default;
};

bool KernelHandleCreate() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  {
    KernelHandle handle(dispatcher);
    EXPECT_EQ(dispatcher.get(), handle.dispatcher().get(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleCreateUpcast() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  {
    KernelHandle<FakeDispatcherBase> handle(dispatcher);
    EXPECT_EQ(dispatcher.get(), handle.dispatcher().get(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleReset() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  fbl::RefPtr<FakeDispatcher> dispatcher2 = FakeDispatcher::Create();
  {
    KernelHandle handle(dispatcher);

    handle.reset(dispatcher2);
    EXPECT_EQ(dispatcher2.get(), handle.dispatcher().get(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");
    EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleResetUpcast() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  fbl::RefPtr<FakeDispatcher> dispatcher2 = FakeDispatcher::Create();
  {
    KernelHandle<FakeDispatcherBase> handle(dispatcher);

    handle.reset(dispatcher2);
    EXPECT_EQ(dispatcher2.get(), handle.dispatcher().get(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");
    EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleResetToNull() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  KernelHandle handle(dispatcher);

  handle.reset();
  EXPECT_NULL(handle.dispatcher(), "");
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleRelease() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  KernelHandle handle(dispatcher);

  fbl::RefPtr<FakeDispatcher> dispatcher_copy = handle.release();
  EXPECT_NULL(handle.dispatcher(), "");
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 0, "");
  EXPECT_EQ(dispatcher.get(), dispatcher_copy.get(), "");

  END_TEST;
}

bool KernelHandleMoveConstructor() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  KernelHandle handle(dispatcher);
  {
    KernelHandle new_handle(ktl::move(handle));
    EXPECT_NULL(handle.dispatcher(), "");
    EXPECT_NONNULL(new_handle.dispatcher(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleMoveConstructorUpcast() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  KernelHandle handle(dispatcher);
  {
    KernelHandle<FakeDispatcherBase> new_handle(ktl::move(handle));
    EXPECT_NULL(handle.dispatcher(), "");
    EXPECT_NONNULL(new_handle.dispatcher(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleMoveAssignment() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  fbl::RefPtr<FakeDispatcher> dispatcher2 = FakeDispatcher::Create();
  {
    KernelHandle handle(dispatcher);
    KernelHandle handle2(dispatcher2);

    handle = ktl::move(handle2);
    EXPECT_NONNULL(handle.dispatcher(), "");
    EXPECT_NULL(handle2.dispatcher(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");
    EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleMoveAssignmentUpcast() {
  BEGIN_TEST;

  fbl::RefPtr<FakeDispatcher> dispatcher = FakeDispatcher::Create();
  fbl::RefPtr<FakeDispatcher> dispatcher2 = FakeDispatcher::Create();
  {
    KernelHandle<FakeDispatcherBase> handle(dispatcher);
    KernelHandle handle2(dispatcher2);

    handle = ktl::move(handle2);
    EXPECT_NONNULL(handle.dispatcher(), "");
    EXPECT_NULL(handle2.dispatcher(), "");
    EXPECT_EQ(dispatcher->on_zero_handles_calls(), 1, "");
    EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 0, "");
  }
  EXPECT_EQ(dispatcher2->on_zero_handles_calls(), 1, "");

  END_TEST;
}

bool KernelHandleUpgrade() {
  BEGIN_TEST;

  // HandleOwner requires a real Dispatcher so we can't use FakeDispatcher
  // here. Use eventpair instead since we can signal the peer to check
  // whether its on_zero_handles() has been called.
  KernelHandle<EventPairDispatcher> eventpair[2];
  zx_rights_t rights;
  ASSERT_EQ(EventPairDispatcher::Create(&eventpair[0], &eventpair[1], &rights), ZX_OK, "");
  {
    HandleOwner handle_owner;
    {
      handle_owner = Handle::Make(ktl::move(eventpair[0]), rights);
      EXPECT_NULL(eventpair[0].dispatcher(), "");
      EXPECT_TRUE(handle_owner, "");
      EXPECT_EQ(handle_owner->rights(), rights, "");
    }
    EXPECT_EQ(eventpair[1].dispatcher()->user_signal_peer(0, ZX_USER_SIGNAL_0), ZX_OK, "");
  }
  EXPECT_EQ(eventpair[1].dispatcher()->user_signal_peer(0, ZX_USER_SIGNAL_0), ZX_ERR_PEER_CLOSED,
            "");

  END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(handle_tests)
UNITTEST("KernelHandleCreate", KernelHandleCreate)
UNITTEST("KernelHandleCreateUpcast", KernelHandleCreateUpcast)
UNITTEST("KernelHandleReset", KernelHandleReset)
UNITTEST("KernelHandleResetUpcast", KernelHandleResetUpcast)
UNITTEST("KernelHandleResetToNull", KernelHandleResetToNull)
UNITTEST("KernelHandleRelease", KernelHandleRelease)
UNITTEST("KernelHandleMoveConstructor", KernelHandleMoveConstructor)
UNITTEST("KernelHandleMoveConstructorUpcast", KernelHandleMoveConstructorUpcast)
UNITTEST("KernelHandleMoveAssignment", KernelHandleMoveAssignment)
UNITTEST("KernelHandleMoveAssignmentUpcast", KernelHandleMoveAssignmentUpcast)
UNITTEST("KernelHandleUpgrade", KernelHandleUpgrade)
UNITTEST_END_TESTCASE(handle_tests, "handle", "Handle test");
