// 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/message_buffer.h>
#include <lib/fidl/cpp/message_builder.h>
#include <lib/zx/channel.h>

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

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!");
  string.Encode(&encoder, 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());

  StringView* view = message.GetPayloadAs<StringView>();
  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!");
  string.Encode(&encoder, 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 = {};
  header.txid = txid;
  header.ordinal = 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!");
  string.Encode(&encoder, 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 = {};
  header.txid = 0;
  header.ordinal = 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 = {};
  header.txid = 0;
  header.ordinal = 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!");
  string.Encode(&encoder, 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 = {};
  header.txid = txid;
  header.ordinal = 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!");
  string.Encode(&encoder, 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 = {};
  header.txid = txid;
  header.ordinal = 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!");
  string.Encode(&encoder, 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!");
    string.Encode(&encoder, 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
