// 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-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/fidl-utils/bind.h>
#include <lib/zx/channel.h>
#include <string.h>
#include <zircon/fidl.h>
#include <zircon/syscalls.h>

#include <utility>

#include <fidl/test/spaceship/c/fidl.h>
#include <zxtest/zxtest.h>

namespace {

class SpaceShip {
 public:
  using SpaceShipBinder = fidl::Binder<SpaceShip>;

  virtual ~SpaceShip() {}

  virtual zx_status_t AdjustHeading(const uint32_t* stars_data, size_t stars_count,
                                    fidl_txn_t* txn) {
    EXPECT_EQ(3u, stars_count, "");
    EXPECT_EQ(11u, stars_data[0], "");
    EXPECT_EQ(0u, stars_data[1], "");
    EXPECT_EQ(UINT32_MAX, stars_data[2], "");
    return fidl_test_spaceship_SpaceShipAdjustHeading_reply(txn, -12);
  }

  virtual zx_status_t ScanForLifeforms(fidl_txn_t* txn) {
    const uint32_t lifesigns[5] = {42u, 43u, UINT32_MAX, 0u, 9u};
    return fidl_test_spaceship_SpaceShipScanForLifeforms_reply(txn, lifesigns, 5);
  }

  virtual zx_status_t ScanForTensorLifeforms(fidl_txn_t* txn) {
    uint32_t lifesigns[8][5][3] = {};
    // fill the array with increasing counter
    uint32_t counter = 0;
    for (size_t i = 0; i < 8; i++) {
      for (size_t j = 0; j < 5; j++) {
        for (size_t k = 0; k < 3; k++) {
          lifesigns[i][j][k] = counter;
          counter += 1;
        }
      }
    }
    return fidl_test_spaceship_SpaceShipScanForTensorLifeforms_reply(txn, lifesigns);
  }

  virtual zx_status_t SetAstrometricsListener(zx_handle_t listener) {
    EXPECT_EQ(ZX_OK, fidl_test_spaceship_AstrometricsListenerOnNova(listener), "");
    EXPECT_EQ(ZX_OK, zx_handle_close(listener), "");
    return ZX_OK;
  }

  virtual zx_status_t SetDefenseCondition(fidl_test_spaceship_Alert alert) {
    EXPECT_EQ(fidl_test_spaceship_Alert_RED, alert, "");
    return ZX_OK;
  }

  virtual zx_status_t GetFuelRemaining(zx_handle_t cancel, fidl_txn_t* txn) {
    EXPECT_EQ(ZX_HANDLE_INVALID, cancel, "");
    const fidl_test_spaceship_FuelLevel level = {
        .reaction_mass = 1641u,
    };
    return fidl_test_spaceship_SpaceShipGetFuelRemaining_reply(txn, ZX_OK, &level);
  }

  virtual zx_status_t AddFuelTank(const fidl_test_spaceship_FuelLevel* level, fidl_txn_t* txn) {
    return fidl_test_spaceship_SpaceShipAddFuelTank_reply(txn, level->reaction_mass / 2);
  }
  virtual zx_status_t ActivateShields(fidl_test_spaceship_Shields shields) { return ZX_OK; }

  virtual zx_status_t Bind(async_dispatcher_t* dispatcher, zx::channel channel) {
    static constexpr fidl_test_spaceship_SpaceShip_ops_t kOps = {
        .AdjustHeading = SpaceShipBinder::BindMember<&SpaceShip::AdjustHeading>,
        .ScanForLifeforms = SpaceShipBinder::BindMember<&SpaceShip::ScanForLifeforms>,
        .SetAstrometricsListener = SpaceShipBinder::BindMember<&SpaceShip::SetAstrometricsListener>,
        .SetDefenseCondition = SpaceShipBinder::BindMember<&SpaceShip::SetDefenseCondition>,
        .GetFuelRemaining = SpaceShipBinder::BindMember<&SpaceShip::GetFuelRemaining>,
        .AddFuelTank = SpaceShipBinder::BindMember<&SpaceShip::AddFuelTank>,
        .ScanForTensorLifeforms = SpaceShipBinder::BindMember<&SpaceShip::ScanForTensorLifeforms>,
        .ActivateShields = SpaceShipBinder::BindMember<&SpaceShip::ActivateShields>,
    };

    return SpaceShipBinder::BindOps<fidl_test_spaceship_SpaceShip_dispatch>(
        dispatcher, std::move(channel), this, &kOps);
  }
};

TEST(SpaceshipTestsCpp, spaceship_test) {
  zx::channel client, server;
  zx_status_t status = zx::channel::create(0, &client, &server);
  ASSERT_EQ(ZX_OK, status, "");

  async_loop_t* loop = NULL;
  ASSERT_EQ(ZX_OK, async_loop_create(&kAsyncLoopConfigNoAttachToCurrentThread, &loop), "");
  ASSERT_EQ(ZX_OK, async_loop_start_thread(loop, "spaceship-dispatcher", NULL), "");

  async_dispatcher_t* dispatcher = async_loop_get_dispatcher(loop);
  SpaceShip ship;
  ASSERT_EQ(ZX_OK, ship.Bind(dispatcher, std::move(server)));

  {
    const uint32_t stars[3] = {11u, 0u, UINT32_MAX};
    int8_t result = 0;
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAdjustHeading(client.get(), stars, 3, &result));
    ASSERT_EQ(-12, result, "");
  }

  {
    constexpr uint32_t kNumStarsOverflow = fidl_test_spaceship_MaxStarsAdjustHeading * 2;
    const uint32_t stars[kNumStarsOverflow] = {};
    int8_t result = 0;
    ASSERT_EQ(ZX_ERR_INVALID_ARGS, fidl_test_spaceship_SpaceShipAdjustHeading(
                                       client.get(), stars, kNumStarsOverflow, &result));
  }

  {
    int8_t result = 0;
    ASSERT_EQ(ZX_ERR_INVALID_ARGS,
              fidl_test_spaceship_SpaceShipAdjustHeading(client.get(), nullptr, 1 << 31, &result));
  }

  {
    uint32_t lifesigns[64];
    size_t actual = 0;
    ASSERT_EQ(ZX_OK,
              fidl_test_spaceship_SpaceShipScanForLifeforms(client.get(), lifesigns, 64, &actual));
    ASSERT_EQ(5u, actual, "");
    ASSERT_EQ(42u, lifesigns[0], "");
    ASSERT_EQ(43u, lifesigns[1], "");
    ASSERT_EQ(UINT32_MAX, lifesigns[2], "");
    ASSERT_EQ(0u, lifesigns[3], "");
    ASSERT_EQ(9u, lifesigns[4], "");
  }

  {
    uint32_t lifesigns[8][5][3];
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipScanForTensorLifeforms(client.get(), lifesigns),
              "");
    uint32_t counter = 0;
    for (size_t i = 0; i < 8; i++) {
      for (size_t j = 0; j < 5; j++) {
        for (size_t k = 0; k < 3; k++) {
          ASSERT_EQ(counter, lifesigns[i][j][k], "");
          counter += 1;
        }
      }
    }
  }

  {
    zx::channel listener_client, listener_server;
    status = zx::channel::create(0, &listener_client, &listener_server);
    ASSERT_EQ(ZX_OK, status, "");
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipSetAstrometricsListener(
                         client.get(), listener_client.release()));
    ASSERT_EQ(ZX_OK, listener_server.wait_one(ZX_CHANNEL_READABLE, zx::time::infinite(), NULL));
    ASSERT_EQ(ZX_OK, zx_handle_close(listener_server.release()));
  }

  {
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipSetDefenseCondition(
                         client.get(), fidl_test_spaceship_Alert_RED));
  }

  {
    fidl_test_spaceship_FuelLevel level;
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipGetFuelRemaining(client.get(), ZX_HANDLE_INVALID,
                                                                   &status, &level));
    ASSERT_EQ(ZX_OK, status, "");
    ASSERT_EQ(1641u, level.reaction_mass, "");
  }

  {
    fidl_test_spaceship_FuelLevel level = {
        .reaction_mass = 9482,
    };
    uint32_t out_consumed = 0u;
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAddFuelTank(client.get(), &level, &out_consumed));
    ASSERT_EQ(4741u, out_consumed, "");
  }

  ASSERT_EQ(ZX_OK, zx_handle_close(client.release()));

  async_loop_destroy(loop);
}

// A variant of spaceship which responds to requests asynchronously.
class AsyncSpaceShip : public SpaceShip {
 public:
  using SpaceShipBinder = fidl::Binder<AsyncSpaceShip>;

  virtual ~AsyncSpaceShip() {}

  // Creates a |fidl_async_txn| using the C++ wrapper, and pushes the
  // computation to a background thread.
  //
  // This background thread responds to the original |txn|, and rebinds the connection
  // to the dispatcher.
  zx_status_t AdjustHeading(const uint32_t* stars_data, size_t stars_count,
                            fidl_txn_t* txn) override {
    EXPECT_EQ(3u, stars_count, "");
    EXPECT_EQ(11u, stars_data[0], "");
    EXPECT_EQ(0u, stars_data[1], "");
    EXPECT_EQ(UINT32_MAX, stars_data[2], "");
    static constexpr auto handler = [](void* arg) {
      auto spaceship = reinterpret_cast<AsyncSpaceShip*>(arg);
      EXPECT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAdjustHeading_reply(
                           spaceship->async_txn_.Transaction(), -12));
      EXPECT_EQ(ZX_OK, spaceship->async_txn_.Rebind());
      return 0;
    };

    async_txn_.Reset(txn);
    EXPECT_EQ(thrd_success, thrd_create(&thrd_, handler, this));
    return ZX_ERR_ASYNC;
  }

  // Creates a |fidl_async_txn| using the C++ wrapper, and pushes the
  // computation to a background thread.
  //
  // This background thread responds to the original |txn|, but does not rebind
  // the connection to the dispatcher. This completes the asynchronous transaction and destroys
  // the original binding.
  zx_status_t ScanForLifeforms(fidl_txn_t* txn) override {
    static constexpr auto handler = [](void* arg) {
      auto spaceship = reinterpret_cast<AsyncSpaceShip*>(arg);
      const uint32_t lifesigns[2] = {42u, 43u};
      EXPECT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipScanForLifeforms_reply(
                           spaceship->async_txn_.Transaction(), lifesigns, 2));
      spaceship->async_txn_.Reset();
      return 0;
    };

    async_txn_.Reset(txn);
    EXPECT_EQ(thrd_success, thrd_create(&thrd_, handler, this));
    return ZX_ERR_ASYNC;
  }

  void Join() {
    int res;
    EXPECT_EQ(thrd_success, thrd_join(thrd_, &res));
    EXPECT_EQ(0, res);
  }

  zx_status_t Bind(async_dispatcher_t* dispatcher, zx::channel channel) override {
    static constexpr fidl_test_spaceship_SpaceShip_ops_t kOps = {
        .AdjustHeading = SpaceShipBinder::BindMember<&AsyncSpaceShip::AdjustHeading>,
        .ScanForLifeforms = SpaceShipBinder::BindMember<&AsyncSpaceShip::ScanForLifeforms>,
        .SetAstrometricsListener = SpaceShipBinder::BindMember<&SpaceShip::SetAstrometricsListener>,
        .SetDefenseCondition = SpaceShipBinder::BindMember<&SpaceShip::SetDefenseCondition>,
        .GetFuelRemaining = SpaceShipBinder::BindMember<&SpaceShip::GetFuelRemaining>,
        .AddFuelTank = SpaceShipBinder::BindMember<&SpaceShip::AddFuelTank>,
        .ScanForTensorLifeforms = SpaceShipBinder::BindMember<&SpaceShip::ScanForTensorLifeforms>,
        .ActivateShields = SpaceShipBinder::BindMember<&SpaceShip::ActivateShields>,
    };

    return SpaceShipBinder::BindOps<fidl_test_spaceship_SpaceShip_dispatch>(
        dispatcher, std::move(channel), this, &kOps);
  }

 private:
  thrd_t thrd_;
  fidl::AsyncTransaction async_txn_;
};

TEST(SpaceshipTestsCpp, spaceship_async_test) {
  zx::channel client, server;
  zx_status_t status = zx::channel::create(0, &client, &server);
  ASSERT_EQ(ZX_OK, status, "");

  async_loop_t* loop = NULL;
  ASSERT_EQ(ZX_OK, async_loop_create(&kAsyncLoopConfigNoAttachToCurrentThread, &loop), "");
  ASSERT_EQ(ZX_OK, async_loop_start_thread(loop, "spaceship-dispatcher", NULL), "");

  async_dispatcher_t* dispatcher = async_loop_get_dispatcher(loop);
  AsyncSpaceShip ship;
  ASSERT_EQ(ZX_OK, ship.Bind(dispatcher, std::move(server)));

  // Try invoking a member function which responds asynchronously and rebinds the connection.
  {
    const uint32_t stars[3] = {11u, 0u, UINT32_MAX};
    int8_t result = 0;
    ASSERT_EQ(ZX_OK, fidl_test_spaceship_SpaceShipAdjustHeading(client.get(), stars, 3, &result));
    ASSERT_EQ(-12, result, "");
    ship.Join();
  }

  // Try invoking a member function which responds asynchronously, but does not rebind the
  // connection. We should be able to observe that the server terminates the connection.
  {
    uint32_t lifesigns[64];
    size_t actual = 0;
    ASSERT_EQ(ZX_OK,
              fidl_test_spaceship_SpaceShipScanForLifeforms(client.get(), lifesigns, 64, &actual));
    ASSERT_EQ(2u, actual, "");
    ASSERT_EQ(42u, lifesigns[0], "");
    ASSERT_EQ(43u, lifesigns[1], "");

    zx_signals_t pending;
    zx::time deadline = zx::deadline_after(zx::sec(5));
    ASSERT_EQ(ZX_OK, client.wait_one(ZX_CHANNEL_PEER_CLOSED, deadline, &pending));
    ASSERT_EQ(pending & ZX_CHANNEL_PEER_CLOSED, ZX_CHANNEL_PEER_CLOSED);
    ship.Join();
  }

  ASSERT_EQ(ZX_OK, zx_handle_close(client.release()));

  async_loop_destroy(loop);
}

// These classes represents a compile-time check:
//
// We should be able to bind a derived class to its own methods,
// but also to methods of the base class.
//
// However, we should not be able to bind to an unrelated class.
class NotDerived {
 public:
  zx_status_t AdjustHeading(const uint32_t* stars_data, size_t stars_count, fidl_txn_t* txn) {
    return ZX_ERR_NOT_SUPPORTED;
  }
};

class Derived : public SpaceShip {
 public:
  using DerivedBinder = fidl::Binder<Derived>;

  zx_status_t ScanForLifeforms(fidl_txn_t* txn) override { return ZX_OK; }

  zx_status_t Bind(async_dispatcher_t* dispatcher, zx::channel channel) override {
    static constexpr fidl_test_spaceship_SpaceShip_ops_t kOps = {
    // (Under the failure case) Tries to bind to a member, such that the
    // context object passed to BindOps does not match the BindMember
    // callback. This should fail at compile time.
#if TEST_WILL_NOT_COMPILE || 0
      .AdjustHeading = DerivedBinder::BindMember<&NotDerived::AdjustHeading>,
#else
      .AdjustHeading = DerivedBinder::BindMember<&SpaceShip::AdjustHeading>,
#endif
      // Binds a member of the derived class to the derived method:
      // This is the typical use case of the Binder object.
      .ScanForLifeforms = DerivedBinder::BindMember<&Derived::ScanForLifeforms>,

      // Binds a member of the derived class to the base method:
      // The compile time check should allow this, because the "Derived"
      // class should be castable to a "SpaceShip" class.
      .SetAstrometricsListener = DerivedBinder::BindMember<&SpaceShip::SetAstrometricsListener>,

      // The remaining functions cover already tested behavior, but just
      // fill the ops table.
      .SetDefenseCondition = DerivedBinder::BindMember<&SpaceShip::SetDefenseCondition>,
      .GetFuelRemaining = DerivedBinder::BindMember<&SpaceShip::GetFuelRemaining>,
      .AddFuelTank = DerivedBinder::BindMember<&SpaceShip::AddFuelTank>,
      .ScanForTensorLifeforms = DerivedBinder::BindMember<&Derived::ScanForTensorLifeforms>,
      .ActivateShields = SpaceShipBinder::BindMember<&Derived::ActivateShields>,
    };

    return SpaceShipBinder::BindOps<fidl_test_spaceship_SpaceShip_dispatch>(
        dispatcher, std::move(channel), this, &kOps);
  }
};

}  // namespace
