// 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/fit/defer.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 {

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<SingleUseMessageHandler>(
      [&callback_count](Message&& message) {
        ++callback_count;
        EXPECT_EQ(42u, message.ordinal());
        return ZX_OK;
      },
      &zero_arg_message_type);

  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<SingleUseMessageHandler>(
      [&callback_count](Message&& message) {
        ++callback_count;
        EXPECT_EQ(42u, message.ordinal());
        return ZX_OK;
      },
      &zero_arg_message_type);

  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<SingleUseMessageHandler>(
      [&callback_count](Message&& message) {
        ++callback_count;
        EXPECT_EQ(42u, message.ordinal());
        return ZX_OK;
      },
      &zero_arg_message_type);

  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 defer = fit::defer([&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<SingleUseMessageHandler>(
        [](Message&& message) { return ZX_OK; }, &zero_arg_message_type);
    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();
  });
  auto handler = std::make_unique<SingleUseMessageHandler>(
      [defer = std::move(defer)](Message&& message) { return ZX_OK; }, &zero_arg_message_type);

  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
