// Copyright 2021 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/fidl/cpp/client.h>
#include <lib/fidl/llcpp/connect_service.h>

#include <array>

#include <zxtest/zxtest.h>

#include "test_messages.h"

namespace {

class TestProtocol {
  TestProtocol() = delete;
};

}  // namespace

// Fake client implementations.
namespace fidl {

template <>
class AsyncEventHandler<TestProtocol> : public fidl::internal::AsyncEventHandler {};

namespace internal {

template <>
class WireClientImpl<TestProtocol> : public ClientBase {
 public:
  void SomeWireMethod() {
    GoodMessage msg;
    fidl::Result result = MakeSyncCallWith([&](std::shared_ptr<zx::channel> channel) {
      zx_status_t status =
          zx_channel_write_etc(channel->get(), 0, static_cast<void*>(msg.message().bytes().data()),
                               msg.message().bytes().actual(), msg.message().handles().data(),
                               msg.message().handles().actual());
      EXPECT_OK(status);
      return fidl::Result::Ok();
    });
    EXPECT_OK(result.status());
  }

 private:
  std::optional<UnbindInfo> DispatchEvent(fidl::IncomingMessage& msg,
                                          AsyncEventHandler* maybe_event_handler) override {
    ZX_PANIC("Not used in this test");
  }
};

template <>
class NaturalClientImpl<TestProtocol> : public NaturalClientBase {
 public:
  using NaturalClientBase::NaturalClientBase;

  void SomeNaturalMethod() const {
    GoodMessage msg;
    fidl::Result result = messenger().OneWay(msg.type(), msg.message());
    EXPECT_OK(result.status());
  }
};

}  // namespace internal
}  // namespace fidl

namespace {

class ClientFixture : public zxtest::Test {
 public:
  ClientFixture() : loop_(&kAsyncLoopConfigNeverAttachToThread) {}

  void SetUp() override {
    zx::status endpoints = fidl::CreateEndpoints<TestProtocol>();
    ASSERT_OK(endpoints.status_value());
    endpoints_ = std::move(*endpoints);
  }

  async::Loop& loop() { return loop_; }

  fidl::Endpoints<TestProtocol>& endpoints() { return endpoints_; }

  fidl::IncomingMessage ReadFromServer() {
    return fidl::ChannelReadEtc(endpoints_.server.channel().get(), 0,
                                fidl::BufferSpan(read_buffer_.data(), read_buffer_.size()),
                                cpp20::span<zx_handle_info_t>{});
  }

 private:
  async::Loop loop_;
  fidl::Endpoints<TestProtocol> endpoints_;
  FIDL_ALIGNDECL std::array<uint8_t, ZX_CHANNEL_MAX_MSG_BYTES> read_buffer_;
};

class Client : public ClientFixture {};
class SharedClient : public ClientFixture {};

TEST_F(Client, DefaultConstruction) {
  fidl::Client<TestProtocol> client;
  EXPECT_FALSE(client.is_valid());
}

TEST_F(SharedClient, DefaultConstruction) {
  fidl::SharedClient<TestProtocol> client;
  EXPECT_FALSE(client.is_valid());
}

TEST_F(Client, Move) {
  fidl::Client<TestProtocol> client;
  client.Bind(std::move(endpoints().client), loop().dispatcher());
  EXPECT_TRUE(client.is_valid());

  fidl::Client<TestProtocol> client2 = std::move(client);
  EXPECT_FALSE(client.is_valid());
  EXPECT_TRUE(client2.is_valid());
  ASSERT_DEATH([&] { client->SomeNaturalMethod(); });
}

TEST_F(SharedClient, Move) {
  fidl::SharedClient<TestProtocol> client;
  client.Bind(std::move(endpoints().client), loop().dispatcher());
  EXPECT_TRUE(client.is_valid());

  fidl::SharedClient<TestProtocol> client2 = std::move(client);
  EXPECT_FALSE(client.is_valid());
  EXPECT_TRUE(client2.is_valid());
  ASSERT_DEATH([&] { client->SomeNaturalMethod(); });
}

TEST_F(SharedClient, Clone) {
  fidl::SharedClient<TestProtocol> client;
  client.Bind(std::move(endpoints().client), loop().dispatcher());
  EXPECT_TRUE(client.is_valid());

  fidl::SharedClient<TestProtocol> client2 = client.Clone();
  EXPECT_TRUE(client.is_valid());
  EXPECT_TRUE(client2.is_valid());
  ASSERT_NO_DEATH([&] { client->SomeNaturalMethod(); });
  ASSERT_NO_DEATH([&] { client2->SomeNaturalMethod(); });
}

TEST_F(Client, WireCall) {
  fidl::Client client(std::move(endpoints().client), loop().dispatcher());
  client.wire()->SomeWireMethod();
  auto msg = ReadFromServer();
  EXPECT_OK(msg.status());
}

TEST_F(SharedClient, WireCall) {
  fidl::SharedClient client(std::move(endpoints().client), loop().dispatcher());
  client.wire()->SomeWireMethod();
  auto msg = ReadFromServer();
  EXPECT_OK(msg.status());
}

TEST_F(Client, NaturalCall) {
  fidl::Client client(std::move(endpoints().client), loop().dispatcher());
  client->SomeNaturalMethod();
  auto msg = ReadFromServer();
  EXPECT_OK(msg.status());
}

TEST_F(SharedClient, NaturalCall) {
  fidl::SharedClient client(std::move(endpoints().client), loop().dispatcher());
  client->SomeNaturalMethod();
  auto msg = ReadFromServer();
  EXPECT_OK(msg.status());
}

}  // namespace
