// 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/stub_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/internal/proxy_controller.h"
#include "lib/fidl/cpp/internal/stub.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));
  }
};

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!");
  fidl::Encode(&encoder, &string, 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!");
    fidl::Encode(&encoder, &string, 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!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

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

  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!");
    fidl::Encode(&encoder, &string, 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!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

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

  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!");
    fidl::Encode(&encoder, &string, 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!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

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

  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!");
  fidl::Encode(&encoder, &string, encoder.Alloc(sizeof(fidl_string_t)));

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

  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
