// Copyright 2022 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/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/time.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <algorithm>
#include <future>
#include <optional>

#include <test/unknown/interactions/cpp/fidl.h>
#include <test/unknown/interactions/cpp/fidl_test_base.h>
#include <zxtest/zxtest.h>

namespace {
namespace test = ::test::unknown_::interactions;

class UnknownInteractionsImpl : public test::testing::UnknownInteractionsProtocol_TestBase {
  void NotImplemented_(const std::string& name) override {
    ADD_FAILURE("Method %s called unexpectedly", name.c_str());
  }
};

class UnknownInteractions : public ::zxtest::Test {
 protected:
  void SetUp() override {
    loop_.emplace(&kAsyncLoopConfigAttachToCurrentThread);

    ASSERT_EQ(zx::channel::create(0, &client_end_, &server_end_), ZX_OK);
  }

  async::Loop& loop() { return loop_.value(); }

  fidl::InterfaceRequest<test::UnknownInteractionsProtocol> TakeServerEnd() {
    EXPECT_TRUE(server_end_.is_valid());
    return fidl::InterfaceRequest<test::UnknownInteractionsProtocol>(std::move(server_end_));
  }

  zx::channel TakeServerChannel() {
    EXPECT_TRUE(server_end_.is_valid());
    return std::move(server_end_);
  }

  zx::channel TakeClientChannel() {
    EXPECT_TRUE(client_end_.is_valid());
    return std::move(client_end_);
  }

  fidl::SynchronousInterfacePtr<test::UnknownInteractionsProtocol> SyncClient() {
    EXPECT_TRUE(client_end_.is_valid());
    fidl::SynchronousInterfacePtr<test::UnknownInteractionsProtocol> client;
    client.Bind(std::move(client_end_));
    return client;
  }

  fidl::InterfacePtr<test::UnknownInteractionsProtocol> AsyncClient() {
    EXPECT_TRUE(client_end_.is_valid());
    fidl::InterfacePtr<test::UnknownInteractionsProtocol> client;
    client.Bind(std::move(client_end_), loop_->dispatcher());
    return client;
  }

 private:
  std::optional<async::Loop> loop_;
  zx::channel client_end_;
  zx::channel server_end_;
};

constexpr std::array<uint8_t, 4> zero_txid = {0, 0, 0, 0};

// Helper for receiving raw data from a channel.
template <uint32_t N>
struct ReadResult {
  // Status from reading.
  zx_status_t status;
  // Bytes from the read.
  std::array<uint8_t, N> buf;
  // Number of bytes read.
  uint32_t num_bytes;
  // Number of handles read.
  uint32_t num_handles;

  ReadResult() = delete;
  // Construct a ReadResult by reading from a channel.
  explicit ReadResult(const zx::channel& channel) {
    status = channel.wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, zx::time::infinite(),
                              nullptr);
    if (status != ZX_OK)
      return;
    status = channel.read(/* flags= */ 0, buf.data(), /* handles= */ nullptr, N,
                          /* num_handles= */ 0, &num_bytes, &num_handles);
  }

  // Get the contents of the buffer excluding the transaction ID.
  std::array<uint8_t, N - 4> buf_excluding_txid() {
    std::array<uint8_t, N - 4> without_txid;
    std::copy(buf.begin() + 4, buf.end(), without_txid.begin());
    return without_txid;
  }

  // Get the transaction id portion of the buffer.
  std::array<uint8_t, 4> buf_txid() {
    std::array<uint8_t, 4> txid;
    std::copy(buf.begin(), buf.begin() + 4, txid.begin());
    return txid;
  }
};

template <uint32_t N>
struct TwoWayServerResult : public ReadResult<N> {
  // Status from sending a reply.
  zx_status_t reply_status;

  TwoWayServerResult() = delete;
  using ReadResult<N>::ReadResult;

  // Helper to send a reply to the read as a two-way message.
  // Copies the txid (first four) bytes from |buf| into |reply_bytes| and sends
  // the result on the channel, storing the status in |reply_status|.
  template <uint32_t M>
  void reply(const zx::channel& channel, std::array<uint8_t, M> reply_bytes) {
    std::copy(this->buf.begin(), this->buf.begin() + 4, reply_bytes.begin());
    reply_status = channel.write(/* flags= */ 0, reply_bytes.data(), M, /* handles= */ nullptr,
                                 /* num_handles= */ 0);
  }
};

TEST_F(UnknownInteractions, OneWayStrictSyncSend) {
  auto client = SyncClient();
  auto server = TakeServerChannel();
  EXPECT_EQ(client->StrictOneWay(), ZX_OK);

  ReadResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
      0xd5, 0x82, 0xb3, 0x4c, 0x50, 0x81, 0xa5, 0x1f,  //
  };
  EXPECT_EQ(received.buf, expected);
}

TEST_F(UnknownInteractions, OneWayFlexibleSyncSend) {
  auto client = SyncClient();
  auto server = TakeServerChannel();
  EXPECT_EQ(client->FlexibleOneWay(), ZX_OK);

  ReadResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01,  //
      0xfc, 0x90, 0xbb, 0xe2, 0x7a, 0x27, 0x93, 0x27,  //
  };
  EXPECT_EQ(received.buf, expected);
}

TEST_F(UnknownInteractions, TwoWayStrictSyncSend) {
  auto client = SyncClient();
  auto server = std::async(std::launch::async, [server = TakeServerChannel()]() {
    TwoWayServerResult<16> result(server);
    result.reply<16>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
                                 0xdc, 0xb0, 0x55, 0x70, 0x95, 0x6f, 0xba, 0x73,  //
                             });
    return result;
  });

  EXPECT_EQ(client->StrictTwoWay(), ZX_OK);

  auto received = server.get();
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  EXPECT_EQ(received.reply_status, ZX_OK);

  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x00, 0x01,                          //
      0xdc, 0xb0, 0x55, 0x70, 0x95, 0x6f, 0xba, 0x73,  //
  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);
}

TEST_F(UnknownInteractions, TwoWayStrictErrSyncSend) {
  auto client = SyncClient();
  auto server = std::async(std::launch::async, [server = TakeServerChannel()]() {
    TwoWayServerResult<16> result(server);
    result.reply<32>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
                                 0xbb, 0x58, 0xe0, 0x08, 0x4e, 0xeb, 0x9b, 0x2e,  //
                                 // Result union with success envelope to satisfy client side:
                                 // ordinal  ---------------------------------|
                                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
                                 // inline value -----|  nhandles |  flags ---|
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,  //

                             });
    return result;
  });

  test::UnknownInteractionsProtocol_StrictTwoWayErr_Result result;
  EXPECT_EQ(client->StrictTwoWayErr(&result), ZX_OK);

  auto received = server.get();
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  EXPECT_EQ(received.reply_status, ZX_OK);

  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x00, 0x01,                          //
      0xbb, 0x58, 0xe0, 0x08, 0x4e, 0xeb, 0x9b, 0x2e,  //
  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);
}

TEST_F(UnknownInteractions, TwoWayFlexibleSyncSend) {
  auto client = SyncClient();
  auto server = std::async(std::launch::async, [server = TakeServerChannel()]() {
    TwoWayServerResult<16> result(server);
    result.reply<32>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01,  //
                                 0x9d, 0x60, 0x95, 0x03, 0x7a, 0x51, 0x33, 0x1f,  //
                                 // Result union with success envelope to satisfy client side:
                                 // ordinal  ---------------------------------|
                                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
                                 // inline value -----|  nhandles |  flags ---|
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,  //

                             });
    return result;
  });

  test::UnknownInteractionsProtocol_FlexibleTwoWay_Result result;
  EXPECT_EQ(client->FlexibleTwoWay(&result), ZX_OK);

  auto received = server.get();
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  EXPECT_EQ(received.reply_status, ZX_OK);

  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x80, 0x01,                          //
      0x9d, 0x60, 0x95, 0x03, 0x7a, 0x51, 0x33, 0x1f,  //

  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);
}

TEST_F(UnknownInteractions, OneWayStrictAsyncSend) {
  auto client = AsyncClient();
  auto server = TakeServerChannel();
  client.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });
  client->StrictOneWay();

  ReadResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
      0xd5, 0x82, 0xb3, 0x4c, 0x50, 0x81, 0xa5, 0x1f,  //
  };
  EXPECT_EQ(received.buf, expected);
}

TEST_F(UnknownInteractions, OneWayFlexibleAsyncSend) {
  auto client = AsyncClient();
  auto server = TakeServerChannel();
  client.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });
  client->FlexibleOneWay();

  ReadResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01,  //
      0xfc, 0x90, 0xbb, 0xe2, 0x7a, 0x27, 0x93, 0x27,  //
  };
  EXPECT_EQ(received.buf, expected);
}

TEST_F(UnknownInteractions, TwoWayStrictAsyncSend) {
  auto client = AsyncClient();
  auto server = TakeServerChannel();
  client.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });

  bool response_received = false;
  client->StrictTwoWay([&response_received]() { response_received = true; });

  TwoWayServerResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x00, 0x01,                          //
      0xdc, 0xb0, 0x55, 0x70, 0x95, 0x6f, 0xba, 0x73,  //
  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);

  received.reply<16>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
                                 0xdc, 0xb0, 0x55, 0x70, 0x95, 0x6f, 0xba, 0x73,  //
                             });
  EXPECT_EQ(received.reply_status, ZX_OK);

  loop().RunUntilIdle();
  EXPECT_TRUE(response_received);
}

TEST_F(UnknownInteractions, TwoWayStrictErrAsyncSend) {
  auto client = AsyncClient();
  auto server = TakeServerChannel();
  client.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });

  bool response_received = false;
  client->StrictTwoWayErr([&response_received](auto response) {
    response_received = true;
    EXPECT_TRUE(response.is_response());
  });

  TwoWayServerResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x00, 0x01,                          //
      0xbb, 0x58, 0xe0, 0x08, 0x4e, 0xeb, 0x9b, 0x2e,  //
  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);

  received.reply<32>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
                                 0xbb, 0x58, 0xe0, 0x08, 0x4e, 0xeb, 0x9b, 0x2e,  //
                                 // Result union with success envelope to satisfy client side:
                                 // ordinal  ---------------------------------|
                                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
                                 // inline value -----|  nhandles |  flags ---|
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,  //

                             });
  EXPECT_EQ(received.reply_status, ZX_OK);

  loop().RunUntilIdle();
  EXPECT_TRUE(response_received);
}

TEST_F(UnknownInteractions, TwoWayFlexibleAsyncSend) {
  auto client = AsyncClient();
  auto server = TakeServerChannel();
  client.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });

  bool response_received = false;
  client->FlexibleTwoWay([&response_received](auto response) { response_received = true; });

  TwoWayServerResult<16> received(server);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);
  std::array<uint8_t, 12> expected{
      0x02, 0x00, 0x80, 0x01,                          //
      0x9d, 0x60, 0x95, 0x03, 0x7a, 0x51, 0x33, 0x1f,  //

  };
  EXPECT_EQ(received.buf_excluding_txid(), expected);
  EXPECT_NE(received.buf_txid(), zero_txid);

  received.reply<32>(server, {
                                 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01,  //
                                 0x9d, 0x60, 0x95, 0x03, 0x7a, 0x51, 0x33, 0x1f,  //
                                 // Result union with success envelope to satisfy client side:
                                 // ordinal  ---------------------------------|
                                 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  //
                                 // inline value -----|  nhandles |  flags ---|
                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,  //

                             });
  EXPECT_EQ(received.reply_status, ZX_OK);

  loop().RunUntilIdle();
  EXPECT_TRUE(response_received);
}

TEST_F(UnknownInteractions, SendStrictEvent) {
  auto client = TakeClientChannel();

  UnknownInteractionsImpl impl;
  fidl::Binding<test::UnknownInteractionsProtocol> binding(&impl);
  auto& event_sender = binding.events();
  binding.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });
  binding.Bind(TakeServerEnd());

  event_sender.StrictEvent();

  ReadResult<16> received(client);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,  //
      0x38, 0x27, 0xa3, 0x91, 0x98, 0x41, 0x4b, 0x58,  //

  };
  EXPECT_EQ(received.buf, expected);
}

TEST_F(UnknownInteractions, SendFlexibleEvent) {
  auto client = TakeClientChannel();

  UnknownInteractionsImpl impl;
  fidl::Binding<test::UnknownInteractionsProtocol> binding(&impl);
  auto& event_sender = binding.events();
  binding.set_error_handler(
      [](zx_status_t status) { ADD_FAILURE("Got an error status: %d", status); });
  binding.Bind(TakeServerEnd());

  event_sender.FlexibleEvent();

  ReadResult<16> received(client);
  EXPECT_EQ(received.status, ZX_OK);
  EXPECT_EQ(received.num_bytes, 16u);
  EXPECT_EQ(received.num_handles, 0u);

  std::array<uint8_t, 16> expected{
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x01,  //
      0x6c, 0x2c, 0x80, 0x0b, 0x8e, 0x1a, 0x7a, 0x31,  //
  };
  EXPECT_EQ(received.buf, expected);
}
}  // namespace
