// 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;

  uint32_t current_handle_count() const { return 0; }
  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")
