// Copyright 2018 The Fuchsia 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 <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <fbl/vector.h>
#include <lib/zx/eventpair.h>
#include <zxtest/zxtest.h>

namespace {

constexpr uint32_t kNumEventpairCombos = 4u;
constexpr uint32_t kNumEventpairsInvalid = 2u;
constexpr uint32_t kOptions = 0u;

void PeerWasClosed(const zx::eventpair& eventpair) {
  zx_signals_t signals;
  ASSERT_OK(eventpair.wait_one(ZX_EVENTPAIR_PEER_CLOSED, zx::time(), &signals));
  ASSERT_EQ(signals & ZX_EVENTPAIR_PEER_CLOSED, ZX_EVENTPAIR_PEER_CLOSED);
}

TEST(HandleCloseTest, Many) {
  zx::eventpair eventpair_0[kNumEventpairCombos];
  zx::eventpair eventpair_1[kNumEventpairCombos];
  zx_handle_t handles[kNumEventpairCombos] = {};

  for (size_t idx = 0u; idx < kNumEventpairCombos; ++idx) {
    ASSERT_OK(zx::eventpair::create(kOptions, &eventpair_0[idx], &eventpair_1[idx]));
    // We don't transfer ownership, just in case close many fails, and we can try
    // closing each handle individually when the test scope exits.
    handles[idx] = eventpair_0[idx].get();
  }
  // Close all of the handles from eventpair_0.
  ASSERT_OK(zx_handle_close_many(handles, kNumEventpairCombos));

  // Verify all the peers of the eventpair were indeed closed.
  for (const auto& eventpair : eventpair_1) {
    ASSERT_NO_FATAL_FAILURES(PeerWasClosed(eventpair));
  }
}

TEST(HandleCloseTest, ManyInvalidHandlesShouldNotFail) {
  // The handles layout: 0 1 2 3 : invalid invalid : 0 1 2 3
  zx::eventpair eventpair_0[kNumEventpairCombos];
  zx::eventpair eventpair_1[kNumEventpairCombos];
  zx_handle_t handles[kNumEventpairCombos + kNumEventpairsInvalid] = {};

  for (size_t idx = 0u; idx < kNumEventpairCombos; ++idx) {
    ASSERT_OK(zx::eventpair::create(kOptions, &eventpair_0[idx], &eventpair_1[idx]));
    // We don't transfer ownership, just in case close many fails, and we can try
    // closing each handle individually when the test scope exits.
    handles[idx] = eventpair_0[idx].get();
  }

  // This invokes close_many with the first 4 valid handles, plus the
  // next two invalid handles, and should close all without failure.
  ASSERT_OK(zx_handle_close_many(handles, kNumEventpairCombos + kNumEventpairsInvalid));

  // Verify all the peers of the eventpair were indeed closed.
  for (const auto& eventpair : eventpair_1) {
    ASSERT_NO_FATAL_FAILURES(PeerWasClosed(eventpair));
  }
}

TEST(HandleCloseTest, ManyDuplicateTest) {
  // The handles layout: 0 1 0 1 2 3 : 0 1 2 3
  zx::eventpair eventpair_0[kNumEventpairCombos];
  zx::eventpair eventpair_1[kNumEventpairCombos];
  zx_handle_t handles[kNumEventpairCombos + kNumEventpairsInvalid] = {};

  for (size_t idx = 0u; idx < kNumEventpairCombos; ++idx) {
    ASSERT_OK(zx::eventpair::create(kOptions, &eventpair_0[idx], &eventpair_1[idx]));
    // We don't transfer ownership, just in case close many fails, and we can try
    // closing each handle individually when the test scope exits.
    handles[idx + kNumEventpairsInvalid] = eventpair_0[idx].get();
  }

  // Duplicate the values at the start.
  handles[0u] = handles[kNumEventpairsInvalid];
  handles[1u] = handles[kNumEventpairsInvalid + 1u];

  // This returns an error value: the duplicated handles
  // can't be closed twice. Despite this, all handles were closed.
  ASSERT_EQ(zx_handle_close_many(handles, kNumEventpairCombos + kNumEventpairsInvalid),
            ZX_ERR_BAD_HANDLE);

  // Assert that every handle in the preceding close call was in
  // fact closed, by waiting on the PEER_CLOSED signal.
  for (const auto& eventpair : eventpair_1) {
    ASSERT_NO_FATAL_FAILURES(PeerWasClosed(eventpair));
  }
}

}  // namespace
