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

#include <ktl/enforce.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")
