// Copyright 2020 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/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/epitaph.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/sync/completion.h>
#include <lib/zx/channel.h>
#include <string.h>
#include <zircon/types.h>

#include <fidl/test/coding/fuchsia/llcpp/fidl.h>
#include <fidl/test/coding/llcpp/fidl.h>
#include <zxtest/zxtest.h>

namespace {

using ::llcpp::fidl::test::coding::fuchsia::Example;

class Server : public Example::Interface {
 public:
  explicit Server(const char* data, size_t size) : data_(data), size_(size) {}

  void TwoWay(fidl::StringView in, TwoWayCompleter::Sync& completer) override {
    ASSERT_EQ(size_, in.size());
    EXPECT_EQ(0, strncmp(data_, in.data(), size_));
    completer.Reply(std::move(in));
  }

  void OneWay(fidl::StringView, OneWayCompleter::Sync&) override {}

 private:
  const char* data_;
  size_t size_;
};

TEST(GenAPITestCase, TwoWayAsyncManaged) {
  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  fidl::Client<Example> client(std::move(local), loop.dispatcher());

  static constexpr char data[] = "TwoWay() sync managed";
  auto server_binding = fidl::BindServer(loop.dispatcher(), std::move(remote),
                                         std::make_unique<Server>(data, sizeof(data)));
  ASSERT_TRUE(server_binding.is_ok());

  sync_completion_t done;
  auto result = client->TwoWay(fidl::StringView(data, sizeof(data)),
                               [&done](Example::TwoWayResponse* response) {
                                 ASSERT_EQ(sizeof(data), response->out.size());
                                 EXPECT_EQ(0, strncmp(response->out.data(), data, sizeof(data)));
                                 sync_completion_signal(&done);
                               });
  ASSERT_TRUE(result.ok());
  ASSERT_OK(sync_completion_wait(&done, ZX_TIME_INFINITE));

  server_binding.value().Unbind();
}

TEST(GenAPITestCase, TwoWayAsyncCallerAllocated) {
  class ResponseContext final : public Example::TwoWayResponseContext {
   public:
    ResponseContext(sync_completion_t* done, const char* data, size_t size)
        : done_(done), data_(data), size_(size) {}

    void OnError() override {
      sync_completion_signal(done_);
      FAIL();
    }

    void OnReply(Example::TwoWayResponse* message) override {
      auto& out = message->out;
      ASSERT_EQ(size_, out.size());
      EXPECT_EQ(0, strncmp(out.data(), data_, size_));
      sync_completion_signal(done_);
    }

   private:
    sync_completion_t* done_;
    const char* data_;
    size_t size_;
  };

  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  fidl::Client<Example> client(std::move(local), loop.dispatcher());

  static constexpr char data[] = "TwoWay() sync caller-allocated";
  auto server_binding = fidl::BindServer(loop.dispatcher(), std::move(remote),
                                         std::make_unique<Server>(data, sizeof(data)));
  ASSERT_TRUE(server_binding.is_ok());

  sync_completion_t done;
  fidl::Buffer<Example::TwoWayRequest> buffer;
  ResponseContext context(&done, data, sizeof(data));
  auto result = client->TwoWay(buffer.view(), fidl::StringView(data, sizeof(data)), &context);
  ASSERT_TRUE(result.ok());
  ASSERT_OK(sync_completion_wait(&done, ZX_TIME_INFINITE));

  server_binding.value().Unbind();
}

TEST(GenAPITestCase, EventManaged) {
  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());

  static constexpr char data[] = "OnEvent() managed";
  class EventHandler : public Example::AsyncEventHandler {
   public:
    EventHandler() = default;

    sync_completion_t& done() { return done_; }

    void OnEvent(Example::OnEventResponse* event) {
      ASSERT_EQ(sizeof(data), event->out.size());
      EXPECT_EQ(0, strncmp(event->out.data(), data, sizeof(data)));
      sync_completion_signal(&done_);
    }

   private:
    sync_completion_t done_;
  };

  auto event_handler = std::make_shared<EventHandler>();
  fidl::Client<Example> client(std::move(local), loop.dispatcher(), event_handler);

  auto server_binding = fidl::BindServer(loop.dispatcher(), std::move(remote),
                                         std::make_unique<Server>(data, sizeof(data)));
  ASSERT_TRUE(server_binding.is_ok());

  // Wait for the event from the server.
  ASSERT_OK(server_binding.value()->OnEvent(fidl::StringView(data, sizeof(data))));
  ASSERT_OK(sync_completion_wait(&event_handler->done(), ZX_TIME_INFINITE));

  server_binding.value().Unbind();
}

// This is test is almost identical to ClientBindingTestCase.Epitaph in llcpp_client_test.cc but
// validates the part of the flow that's handled in the generated code.
TEST(GenAPITestCase, Epitaph) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());

  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  sync_completion_t unbound;

  class EventHandler : public Example::AsyncEventHandler {
   public:
    explicit EventHandler(sync_completion_t& unbound) : unbound_(unbound) {}

    void Unbound(fidl::UnbindInfo info) override {
      EXPECT_EQ(fidl::UnbindInfo::kPeerClosed, info.reason);
      EXPECT_EQ(ZX_ERR_BAD_STATE, info.status);
      sync_completion_signal(&unbound_);
    };

   private:
    sync_completion_t& unbound_;
  };

  fidl::Client<Example> client(std::move(local), loop.dispatcher(),
                               std::make_shared<EventHandler>(unbound));

  // Send an epitaph and wait for on_unbound to run.
  ASSERT_OK(fidl_epitaph_write(remote.get(), ZX_ERR_BAD_STATE));
  EXPECT_OK(sync_completion_wait(&unbound, ZX_TIME_INFINITE));
}

TEST(GenAPITestCase, UnbindInfoEncodeError) {
  class ErrorServer : public Example::Interface {
   public:
    explicit ErrorServer() {}

    void TwoWay(fidl::StringView in, TwoWayCompleter::Sync& completer) override {
      // Fail to send the reply due to an encoding error (the buffer is too
      // small).
      fidl::BufferSpan empty;
      EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL, completer.Reply(empty, std::move(in)).status());
      completer.Close(ZX_OK);  // This should not panic.
    }

    void OneWay(fidl::StringView, OneWayCompleter::Sync&) override {}
  };

  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  fidl::Client<Example> client(std::move(local), loop.dispatcher());

  sync_completion_t done;
  fidl::OnUnboundFn<ErrorServer> on_unbound = [&done](ErrorServer*, fidl::UnbindInfo info,
                                                      zx::channel) {
    EXPECT_EQ(fidl::UnbindInfo::kEncodeError, info.reason);
    EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL, info.status);
    sync_completion_signal(&done);
  };
  auto server = std::make_unique<ErrorServer>();
  auto server_binding =
      fidl::BindServer(loop.dispatcher(), std::move(remote), server.get(), std::move(on_unbound));
  ASSERT_TRUE(server_binding.is_ok());

  // Make a synchronous call which should fail as a result of the server end closing.
  auto result = client->TwoWay_Sync(fidl::StringView("", 0));
  ASSERT_FALSE(result.ok());
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, result.status());

  // Wait for the unbound handler to run.
  ASSERT_OK(sync_completion_wait(&done, ZX_TIME_INFINITE));
}

TEST(GenAPITestCase, UnbindInfoDecodeError) {
  zx::channel local, remote;
  ASSERT_OK(zx::channel::create(0, &local, &remote));

  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  sync_completion_t done;

  class EventHandler : public Example::AsyncEventHandler {
   public:
    EventHandler(sync_completion_t& done) : done_(done) {}

    void OnEvent(Example::OnEventResponse* event) override {
      FAIL();
      sync_completion_signal(&done_);
    }

    void Unbound(fidl::UnbindInfo info) override {
      EXPECT_EQ(fidl::UnbindInfo::kDecodeError, info.reason);
      sync_completion_signal(&done_);
    };

   private:
    sync_completion_t& done_;
  };

  fidl::Client<Example> client(std::move(local), loop.dispatcher(),
                               std::make_shared<EventHandler>(done));

  // Set up an Example.OnEvent() message but send it without the payload. This should trigger a
  // decoding error.
  Example::OnEventResponse resp{fidl::StringView("", 0)};
  fidl::OwnedEncodedMessage<Example::OnEventResponse> encoded(&resp);
  ASSERT_TRUE(encoded.ok());
  ASSERT_OK(remote.write(0, encoded.GetOutgoingMessage().bytes(), sizeof(fidl_message_header_t),
                         nullptr, 0));

  ASSERT_OK(sync_completion_wait(&done, ZX_TIME_INFINITE));
}

}  // namespace
