// Copyright 2017 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 <platform.h>

#include <kernel/semaphore.h>
#include <kernel/thread_lock.h>
#include <lockdep/lockdep.h>

using lockdep::Guard;

static bool smoke_test() {
  BEGIN_TEST;

  {
    Semaphore sema;
    ASSERT_EQ(0u, sema.count());
    ASSERT_EQ(0u, sema.num_waiters());
  }

  {
    Semaphore sema(0);
    ASSERT_EQ(0u, sema.count());
    ASSERT_EQ(0u, sema.num_waiters());
  }

  {
    Semaphore sema(5);
    ASSERT_EQ(5u, sema.count());
    ASSERT_EQ(0u, sema.num_waiters());
  }

  {
    constexpr uint64_t kPostCount = 10;
    Semaphore sema;

    for (uint64_t i = 0; i < kPostCount; ++i) {
      ASSERT_EQ(i, sema.count());
      ASSERT_EQ(0u, sema.num_waiters());

      sema.Post();

      ASSERT_EQ(i + 1, sema.count());
      ASSERT_EQ(0u, sema.num_waiters());
    }

    for (uint64_t i = 0; i < kPostCount; ++i) {
      ASSERT_EQ(kPostCount - i, sema.count());
      ASSERT_EQ(0u, sema.num_waiters());

      ASSERT_EQ(ZX_OK, sema.Wait(Deadline::infinite()));

      ASSERT_EQ(kPostCount - i - 1, sema.count());
      ASSERT_EQ(0u, sema.num_waiters());
    }
  }

  END_TEST;
}

static bool timeout_test() {
  BEGIN_TEST;

  auto dealine = Deadline::after(ZX_USEC(10));

  Semaphore sema;
  ASSERT_EQ(0u, sema.count());
  ASSERT_EQ(0u, sema.num_waiters());
  ASSERT_EQ(ZX_ERR_TIMED_OUT, sema.Wait(dealine));
  ASSERT_EQ(0u, sema.count());
  ASSERT_EQ(0u, sema.num_waiters());

  END_TEST;
}

static int wait_sema_thread(void* arg) {
  auto sema = reinterpret_cast<Semaphore*>(arg);
  auto status = sema->Wait(Deadline::infinite());
  return static_cast<int>(status);
}

static bool thread_is_blocked(const Thread* t) {
  Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
  return (t->state() == THREAD_BLOCKED);
}

enum class Signal { kPost, kKill, kSuspend };

template <Signal signal>
static bool signal_test() {
  BEGIN_TEST;

  Semaphore sema;

  ASSERT_EQ(0u, sema.count());
  ASSERT_EQ(0u, sema.num_waiters());

  auto thread = Thread::Create("test semaphore", wait_sema_thread, &sema, DEFAULT_PRIORITY);

  ASSERT(nullptr != thread);
  thread->Resume();

  while (thread_is_blocked(thread) == false) {
    Thread::Current::SleepRelative(ZX_MSEC(1));
  }

  ASSERT_EQ(0u, sema.count());
  ASSERT_EQ(1u, sema.num_waiters());

  int expected_error;
  switch (signal) {
    case Signal::kPost:
      sema.Post();
      expected_error = ZX_OK;
      break;

    case Signal::kKill:
      thread->Kill();
      expected_error = ZX_ERR_INTERNAL_INTR_KILLED;
      break;

    case Signal::kSuspend:
      thread->Suspend();
      expected_error = ZX_ERR_INTERNAL_INTR_RETRY;
      break;
  }

  int retcode = ZX_OK;
  thread->Join(&retcode, ZX_TIME_INFINITE);
  ASSERT_EQ(expected_error, retcode);

  ASSERT_EQ(0u, sema.count());
  ASSERT_EQ(0u, sema.num_waiters());

  END_TEST;
}

UNITTEST_START_TESTCASE(semaphore_tests)
UNITTEST("smoke_test", smoke_test)
UNITTEST("timeout_test", timeout_test)
UNITTEST("post_signal_test", signal_test<Signal::kPost>)
UNITTEST("kill_signal_test", signal_test<Signal::kKill>)
UNITTEST("suspend_signal_test", signal_test<Signal::kSuspend>)
UNITTEST_END_TESTCASE(semaphore_tests, "semaphore", "Semaphore tests")
