// 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 <lib/async-testing/dispatcher_stub.h>
#include <lib/async/cpp/trap.h>

#include <zxtest/zxtest.h>

namespace {

const zx_handle_t dummy_guest = static_cast<zx_handle_t>(1);
const zx_vaddr_t dummy_addr = 0x1000;
const size_t dummy_length = 0x1000;
const zx_packet_guest_bell_t dummy_bell{
    .addr = dummy_addr,
    .reserved0 = 0u,
    .reserved1 = 0u,
    .reserved2 = 0u,
};

class MockDispatcher : public async::DispatcherStub {
 public:
  zx_status_t SetGuestBellTrap(async_guest_bell_trap_t* trap, const zx::guest& guest,
                               zx_vaddr_t addr, size_t length) override {
    last_trap = trap;
    last_guest = guest.get();
    last_addr = addr;
    last_length = length;
    return ZX_OK;
  }

  async_guest_bell_trap_t* last_trap = nullptr;
  zx_handle_t last_guest = ZX_HANDLE_INVALID;
  zx_vaddr_t last_addr = 0u;
  size_t last_length = 0u;
};

class Harness {
 public:
  void Handler(async_dispatcher_t* dispatcher, async::GuestBellTrapBase* trap, zx_status_t status,
               const zx_packet_guest_bell_t* bell) {
    handler_ran = true;
    last_trap = trap;
    last_status = status;
    last_bell = bell;
  }

  virtual async::GuestBellTrapBase& trap() = 0;

  bool handler_ran = false;
  async::GuestBellTrapBase* last_trap = nullptr;
  zx_status_t last_status = ZX_ERR_INTERNAL;
  const zx_packet_guest_bell_t* last_bell = nullptr;
};

class LambdaHarness : public Harness {
 public:
  async::GuestBellTrapBase& trap() override { return trap_; }

 private:
  async::GuestBellTrap trap_{
      [this](async_dispatcher_t* dispatcher, async::GuestBellTrap* trap, zx_status_t status,
             const zx_packet_guest_bell_t* bell) { Handler(dispatcher, trap, status, bell); }};
};

class MethodHarness : public Harness {
 public:
  async::GuestBellTrapBase& trap() override { return trap_; }

 private:
  async::GuestBellTrapMethod<Harness, &Harness::Handler> trap_{this};
};

TEST(TrapTests, guest_bell_trap_set_handler_test) {
  {
    async::GuestBellTrap trap;
    EXPECT_FALSE(trap.has_handler());

    trap.set_handler([](async_dispatcher_t* dispatcher, async::GuestBellTrap* trap,
                        zx_status_t status, const zx_packet_guest_bell_t* bell) {});
    EXPECT_TRUE(trap.has_handler());
  }

  {
    async::GuestBellTrap trap([](async_dispatcher_t* dispatcher, async::GuestBellTrap* trap,
                                 zx_status_t status, const zx_packet_guest_bell_t* bell) {});
    EXPECT_TRUE(trap.has_handler());
  }
}

template <typename Harness>
void guest_bell_trap_test() {
  MockDispatcher dispatcher;
  Harness harness;

  EXPECT_EQ(ZX_OK, harness.trap().SetTrap(&dispatcher, *zx::unowned_guest(dummy_guest), dummy_addr,
                                          dummy_length));
  EXPECT_EQ(dummy_guest, dispatcher.last_guest);
  EXPECT_EQ(dummy_addr, dispatcher.last_addr);
  EXPECT_EQ(dummy_length, dispatcher.last_length);

  dispatcher.last_trap->handler(&dispatcher, dispatcher.last_trap, ZX_OK, &dummy_bell);
  EXPECT_TRUE(harness.handler_ran);
  EXPECT_EQ(&harness.trap(), harness.last_trap);
  EXPECT_EQ(ZX_OK, harness.last_status);
  EXPECT_EQ(&dummy_bell, harness.last_bell);
}

}  // namespace

TEST(TrapTests, guest_bell_trap_test_LambdaHarness) { guest_bell_trap_test<LambdaHarness>(); }

TEST(TrapTests, guest_bell_trap_test_MethodHarness) { guest_bell_trap_test<MethodHarness>(); }
