// 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/fidl/cpp/internal/proxy_controller.h"

#include <lib/fidl/cpp/message_buffer.h>
#include <lib/fidl/cpp/message_builder.h>
#include <lib/zx/channel.h>

#include "gtest/gtest.h"
#include "lib/fidl/cpp/string.h"
#include "lib/fidl/cpp/test/async_loop_for_test.h"
#include "lib/fidl/cpp/test/fidl_types.h"
#include "lib/fidl/txn_header.h"

namespace fidl {
namespace internal {
namespace {

class CallbackMessageHandler : public MessageHandler {
 public:
  fit::function<zx_status_t(Message)> callback;

  zx_status_t OnMessage(Message message) override { return callback(std::move(message)); }
};

class DestructorMessageHandler : public MessageHandler {
 public:
  fit::function<void()> destructor;

  ~DestructorMessageHandler() { destructor(); }

  zx_status_t OnMessage(Message message) override { return ZX_OK; }
};

TEST(ProxyController, Trivial) { ProxyController controller; }

TEST(ProxyController, Send) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  Encoder encoder(5u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  EXPECT_EQ(ZX_OK, controller.Send(&unbounded_nonnullable_string_message_type, encoder.GetMessage(),
                                   nullptr));

  MessageBuffer buffer;
  Message message = buffer.CreateEmptyMessage();
  EXPECT_EQ(ZX_OK, message.Read(h2.get(), 0));
  EXPECT_EQ(0u, message.txid());
  EXPECT_EQ(5u, message.ordinal());

  fidl_string_t* view = message.GetPayloadAs<fidl_string_t>();
  EXPECT_EQ(6u, view->size);
}

TEST(ProxyController, Callback) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  Encoder encoder(3u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  int callback_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&callback_count](Message message) {
    ++callback_count;
    EXPECT_EQ(42u, message.ordinal());
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, controller.Send(&unbounded_nonnullable_string_message_type, encoder.GetMessage(),
                                   std::move(handler)));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(0, callback_count);

  MessageBuffer buffer;
  Message message = buffer.CreateEmptyMessage();
  EXPECT_EQ(ZX_OK, message.Read(h2.get(), 0));
  EXPECT_NE(0u, message.txid());
  EXPECT_EQ(3u, message.ordinal());

  zx_txid_t txid = message.txid();
  fidl_message_header_t header = {};
  fidl_init_txn_header(&header, txid, 42u);

  EXPECT_EQ(ZX_OK, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
}

TEST(ProxyController, BadSend) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  Encoder encoder(3u);
  // Bad message format.

  int error_count = 0;
  controller.reader().set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_PEER_CLOSED, status);
    ++error_count;
  });

  EXPECT_EQ(0, error_count);
  EXPECT_EQ(ZX_ERR_INVALID_ARGS, controller.Send(&unbounded_nonnullable_string_message_type,
                                                 encoder.GetMessage(), nullptr));
  EXPECT_EQ(0, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(0, error_count);

  EXPECT_EQ(ZX_OK, controller.reader().Unbind().replace(ZX_RIGHT_WAIT, &h1));
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  encoder.Reset(35u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  EXPECT_EQ(0, error_count);
  EXPECT_EQ(ZX_ERR_ACCESS_DENIED, controller.Send(&unbounded_nonnullable_string_message_type,
                                                  encoder.GetMessage(), nullptr));
  EXPECT_EQ(0, error_count);
}

TEST(ProxyController, BadReply) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  zx_status_t expected_error = ZX_ERR_NOT_SUPPORTED;
  int error_count = 0;
  controller.reader().set_error_handler([&expected_error, &error_count](zx_status_t status) {
    EXPECT_EQ(expected_error, status);
    ++error_count;
  });

  fidl_message_header_t header = {};
  fidl_init_txn_header(&header, 0, 42u);

  EXPECT_EQ(ZX_OK, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(0, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, error_count);

  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  header.txid = 42u;

  expected_error = ZX_ERR_NOT_FOUND;
  EXPECT_EQ(ZX_OK, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(1, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(2, error_count);
}

TEST(ProxyController, ShortReply) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  int expected_error = ZX_ERR_NOT_SUPPORTED;
  int error_count = 0;
  controller.reader().set_error_handler([&expected_error, &error_count](zx_status_t status) {
    EXPECT_EQ(expected_error, status);
    ++error_count;
  });

  fidl_message_header_t header = {};
  fidl_init_txn_header(&header, 0, 42u);

  EXPECT_EQ(ZX_OK, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(0, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, error_count);

  expected_error = ZX_ERR_INVALID_ARGS;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  header.txid = 42u;

  EXPECT_EQ(ZX_OK, h2.write(0, "a", 1, nullptr, 0));

  EXPECT_EQ(1, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(2, error_count);
}

TEST(ProxyController, Move) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller1;
  EXPECT_EQ(ZX_OK, controller1.reader().Bind(std::move(h1)));

  Encoder encoder(3u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  int callback_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&callback_count](Message message) {
    ++callback_count;
    EXPECT_EQ(42u, message.ordinal());
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, controller1.Send(&unbounded_nonnullable_string_message_type,
                                    encoder.GetMessage(), std::move(handler)));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(0, callback_count);

  MessageBuffer buffer;
  Message message = buffer.CreateEmptyMessage();
  EXPECT_EQ(ZX_OK, message.Read(h2.get(), 0));
  EXPECT_NE(0u, message.txid());
  EXPECT_EQ(3u, message.ordinal());

  ProxyController controller2 = std::move(controller1);
  EXPECT_FALSE(controller1.reader().is_bound());
  EXPECT_TRUE(controller2.reader().is_bound());

  zx_txid_t txid = message.txid();
  fidl_message_header_t header = {};
  fidl_init_txn_header(&header, txid, 42u);

  EXPECT_EQ(ZX_OK, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
}

TEST(ProxyController, Reset) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  Encoder encoder(3u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  int callback_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&callback_count](Message message) {
    ++callback_count;
    EXPECT_EQ(42u, message.ordinal());
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, controller.Send(&unbounded_nonnullable_string_message_type, encoder.GetMessage(),
                                   std::move(handler)));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(0, callback_count);

  MessageBuffer buffer;
  Message message = buffer.CreateEmptyMessage();
  EXPECT_EQ(ZX_OK, message.Read(h2.get(), 0));
  EXPECT_NE(0u, message.txid());
  EXPECT_EQ(3u, message.ordinal());

  controller.Reset();
  EXPECT_FALSE(controller.reader().is_bound());

  zx_txid_t txid = message.txid();
  fidl_message_header_t header = {};
  fidl_init_txn_header(&header, txid, 42u);

  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h2.write(0, &header, sizeof(fidl_message_header_t), nullptr, 0));

  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(0, callback_count);
}

TEST(ProxyController, ReentrantDestructor) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  fidl::test::AsyncLoopForTest loop;

  ProxyController controller;
  EXPECT_EQ(ZX_OK, controller.reader().Bind(std::move(h1)));

  Encoder encoder(3u);
  StringPtr string("hello!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

  int destructor_count = 0;
  auto handler = std::make_unique<DestructorMessageHandler>();
  handler->destructor = [&destructor_count, &controller]() {
    ++destructor_count;
    EXPECT_EQ(destructor_count, 1);

    Encoder encoder(3u);
    StringPtr string("world!");
    fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));
    auto callback_handler = std::make_unique<CallbackMessageHandler>();
    callback_handler->callback = [](Message message) { return ZX_OK; };
    zx_status_t status = controller.Send(&unbounded_nonnullable_string_message_type,
                                         encoder.GetMessage(), std::move(callback_handler));
    EXPECT_EQ(ZX_ERR_BAD_HANDLE, status);

    controller.Reset();
  };

  EXPECT_EQ(ZX_OK, controller.Send(&unbounded_nonnullable_string_message_type, encoder.GetMessage(),
                                   std::move(handler)));

  loop.RunUntilIdle();

  EXPECT_EQ(destructor_count, 0);
  controller.Reset();
  EXPECT_EQ(destructor_count, 1);
  EXPECT_FALSE(controller.reader().is_bound());

  loop.RunUntilIdle();
  EXPECT_EQ(destructor_count, 1);
}

}  // namespace
}  // namespace internal
}  // namespace fidl
