// 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/internal/stub.h"
#include "lib/fidl/cpp/internal/stub_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 CallbackStub : public Stub {
 public:
  fit::function<zx_status_t(Message, PendingResponse)> callback;

  zx_status_t Dispatch_(Message message, PendingResponse response) override {
    return callback(std::move(message), std::move(response));
  }
};

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

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

TEST(StubController, Trivial) { StubController controller; }

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

  fidl::test::AsyncLoopForTest loop;

  StubController stub_ctrl;
  EXPECT_EQ(ZX_OK, stub_ctrl.reader().Bind(std::move(h1)));

  ProxyController proxy_ctrl;
  EXPECT_EQ(ZX_OK, proxy_ctrl.reader().Bind(std::move(h2)));

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count](Message message, PendingResponse response) {
    ++callback_count;
    EXPECT_EQ(5u, message.ordinal());
    EXPECT_FALSE(response.needs_response());
    EXPECT_EQ(
        ZX_ERR_BAD_STATE,
        response.Send(&unbounded_nonnullable_string_message_type, Message()));
    return ZX_OK;
  };

  stub_ctrl.set_stub(&stub);

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

  EXPECT_EQ(ZX_OK, proxy_ctrl.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage(), nullptr));
  EXPECT_EQ(0, callback_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
}

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

  fidl::test::AsyncLoopForTest loop;

  StubController stub_ctrl;
  EXPECT_EQ(ZX_OK, stub_ctrl.reader().Bind(std::move(h1)));

  ProxyController proxy_ctrl;
  EXPECT_EQ(ZX_OK, proxy_ctrl.reader().Bind(std::move(h2)));

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count](Message message, PendingResponse response) {
    ++callback_count;
    EXPECT_EQ(5u, message.ordinal());
    EXPECT_TRUE(response.needs_response());
    Encoder encoder(42u);
    StringPtr string("welcome!");
    string.Encode(&encoder, encoder.Alloc(sizeof(fidl_string_t)));
    EXPECT_EQ(ZX_OK, response.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage()));
    return ZX_OK;
  };

  stub_ctrl.set_stub(&stub);

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

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

  EXPECT_EQ(ZX_OK, proxy_ctrl.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage(), std::move(handler)));
  EXPECT_EQ(0, callback_count);
  EXPECT_EQ(0, response_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(1, response_count);
}

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

  fidl::test::AsyncLoopForTest loop;

  StubController stub_ctrl;
  EXPECT_EQ(ZX_OK, stub_ctrl.reader().Bind(std::move(h1)));

  ProxyController proxy_ctrl;
  EXPECT_EQ(ZX_OK, proxy_ctrl.reader().Bind(std::move(h2)));

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count, &stub_ctrl](Message message,
                                                PendingResponse response) {
    ++callback_count;

    stub_ctrl.reader().Unbind();

    EXPECT_EQ(5u, message.ordinal());
    EXPECT_TRUE(response.needs_response());
    Encoder encoder(42u);
    StringPtr string("welcome!");
    string.Encode(&encoder, encoder.Alloc(sizeof(fidl_string_t)));
    EXPECT_EQ(ZX_ERR_BAD_STATE,
              response.Send(&unbounded_nonnullable_string_message_type,
                            encoder.GetMessage()));
    return ZX_OK;
  };

  stub_ctrl.set_stub(&stub);

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

  int response_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&response_count](Message message) {
    ++response_count;
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, proxy_ctrl.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage(), std::move(handler)));
  EXPECT_EQ(0, callback_count);
  EXPECT_EQ(0, response_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(0, response_count);
}

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

  fidl::test::AsyncLoopForTest loop;

  auto stub_ctrl = std::make_unique<StubController>();
  EXPECT_EQ(ZX_OK, stub_ctrl->reader().Bind(std::move(h1)));

  ProxyController proxy_ctrl;
  EXPECT_EQ(ZX_OK, proxy_ctrl.reader().Bind(std::move(h2)));

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count, &stub_ctrl](Message message,
                                                PendingResponse response) {
    ++callback_count;

    stub_ctrl.reset();

    EXPECT_EQ(5u, message.ordinal());
    EXPECT_TRUE(response.needs_response());
    Encoder encoder(42u);
    StringPtr string("welcome!");
    string.Encode(&encoder, encoder.Alloc(sizeof(fidl_string_t)));
    EXPECT_EQ(ZX_ERR_BAD_STATE,
              response.Send(&unbounded_nonnullable_string_message_type,
                            encoder.GetMessage()));
    return ZX_OK;
  };

  stub_ctrl->set_stub(&stub);

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

  int response_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&response_count](Message message) {
    ++response_count;
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, proxy_ctrl.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage(), std::move(handler)));
  EXPECT_EQ(0, callback_count);
  EXPECT_EQ(0, response_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(0, response_count);
}

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

  fidl::test::AsyncLoopForTest loop;

  StubController stub_ctrl;
  EXPECT_EQ(ZX_OK, stub_ctrl.reader().Bind(std::move(h1)));

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

  ProxyController proxy_ctrl;
  EXPECT_EQ(ZX_OK, proxy_ctrl.reader().Bind(std::move(h2)));

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count](Message message, PendingResponse response) {
    ++callback_count;
    EXPECT_EQ(5u, message.ordinal());
    EXPECT_TRUE(response.needs_response());
    Encoder encoder(42u);
    // Bad message format.
    EXPECT_EQ(ZX_ERR_INVALID_ARGS,
              response.Send(&unbounded_nonnullable_string_message_type,
                            encoder.GetMessage()));
    return ZX_OK;
  };

  stub_ctrl.set_stub(&stub);

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

  int response_count = 0;
  auto handler = std::make_unique<CallbackMessageHandler>();
  handler->callback = [&response_count](Message message) {
    ++response_count;
    return ZX_OK;
  };

  EXPECT_EQ(ZX_OK, proxy_ctrl.Send(&unbounded_nonnullable_string_message_type,
                                   encoder.GetMessage(), std::move(handler)));
  EXPECT_EQ(0, callback_count);
  EXPECT_EQ(0, response_count);
  EXPECT_EQ(0, error_count);
  loop.RunUntilIdle();
  EXPECT_EQ(1, callback_count);
  EXPECT_EQ(0, response_count);
  EXPECT_EQ(0, error_count);
}

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

  fidl::test::AsyncLoopForTest loop;

  StubController stub_ctrl;
  EXPECT_EQ(ZX_OK, stub_ctrl.reader().Bind(std::move(h1)));

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

  CallbackStub stub;

  int callback_count = 0;
  stub.callback = [&callback_count](Message message, PendingResponse response) {
    ++callback_count;
    return ZX_OK;
  };

  stub_ctrl.set_stub(&stub);

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

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

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