// Copyright 2022 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/driver2/runtime.h>
#include <lib/driver2/runtime_connector_impl.h>
#include <lib/service/llcpp/service.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>

#include <set>

#include <gtest/gtest.h>

#include "src/lib/testing/loop_fixture/real_loop_fixture.h"

namespace fdf {
using namespace fuchsia_driver_framework;
}  // namespace fdf

namespace fio = fuchsia_io;

class RuntimeConnectorTest : public gtest::RealLoopFixture {
 public:
  void SetUp() override {
    RealLoopFixture::SetUp();

    runtime_connector_ = std::make_unique<driver::RuntimeConnectorImpl>(dispatcher());

    // Setup the outgoing directory.
    outgoing_ = std::make_unique<component::OutgoingDirectory>(
        component::OutgoingDirectory::Create(dispatcher()));

    auto service = [this](fidl::ServerEnd<fdf::RuntimeConnector> server_end) {
      fidl::BindServer(dispatcher(), std::move(server_end), runtime_connector_.get());
    };
    ASSERT_EQ(ZX_OK,
              outgoing_->AddProtocol<fdf::RuntimeConnector>(std::move(service)).status_value());

    auto endpoints = fidl::CreateEndpoints<fio::Directory>();
    ASSERT_EQ(ZX_OK, endpoints.status_value());

    ASSERT_EQ(ZX_OK, outgoing_->Serve(std::move(endpoints->server)).status_value());
    root_dir_ = fidl::WireClient<fuchsia_io::Directory>(std::move(endpoints->client), dispatcher());
  }

  zx::status<fidl::WireSharedClient<fdf::RuntimeConnector>> CreateRuntimeConnectorClient() {
    zx::channel server_end, client_end;
    auto status = zx::channel::create(0, &server_end, &client_end);
    if (status != ZX_OK) {
      return zx::error(status);
    }
    auto open = root_dir_->Open(
        fuchsia_io::wire::OpenFlags::kRightWritable | fuchsia_io::wire::OpenFlags::kRightReadable,
        fuchsia_io::wire::kModeTypeDirectory, "svc",
        fidl::ServerEnd<fuchsia_io::Node>(std::move(server_end)));
    if (!open.ok()) {
      return zx::error(ZX_ERR_IO);
    }
    fidl::ClientEnd<fuchsia_io::Directory> fidl_client_end(std::move(client_end));
    auto svc = service::ConnectAt<fdf::RuntimeConnector>(std::move(fidl_client_end));
    if (!svc.is_ok()) {
      return svc.take_error();
    }
    return zx::ok(fidl::WireSharedClient<fdf::RuntimeConnector>(std::move(*svc), dispatcher()));
  }

  void TearDown() override { RealLoopFixture::TearDown(); }

 protected:
  std::unique_ptr<driver::RuntimeConnectorImpl> runtime_connector_;
  std::unique_ptr<component::OutgoingDirectory> outgoing_;
  fidl::WireClient<fuchsia_io::Directory> root_dir_;
};

TEST_F(RuntimeConnectorTest, ConnectSuccess) {
  static constexpr const char* kProtocol = "test";

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto channels = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channels.is_error());

  std::atomic_bool server_called = false;
  runtime_connector_->RegisterProtocol(kProtocol, [&](fdf::Channel channel) -> zx_status_t {
    server_called = true;
    return ZX_OK;
  });

  async::Executor executor(dispatcher());
  auto task = driver::ConnectToRuntimeProtocol<void>(*runtime_connector_client, kProtocol)
                  .then([quit_loop = QuitLoopClosure()](
                            fpromise::result<fdf::Channel, zx_status_t>& result) {
                    ASSERT_TRUE(result.is_ok());
                    quit_loop();
                  });
  executor.schedule_task(std::move(task));

  RunLoop();
  ASSERT_TRUE(server_called);
}

TEST_F(RuntimeConnectorTest, ConnectFailRejectedByServer) {
  static constexpr const char* kProtocol = "test";

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto channels = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channels.is_error());

  std::atomic_bool server_called = false;
  runtime_connector_->RegisterProtocol(kProtocol, [&](fdf::Channel channel) -> zx_status_t {
    server_called = true;
    return ZX_ERR_INTERNAL;
  });

  async::Executor executor(dispatcher());
  auto task = driver::ConnectToRuntimeProtocol<void>(*runtime_connector_client, kProtocol)
                  .then([quit_loop = QuitLoopClosure()](
                            fpromise::result<fdf::Channel, zx_status_t>& result) {
                    ASSERT_FALSE(result.is_ok());
                    quit_loop();
                  });
  executor.schedule_task(std::move(task));

  RunLoop();
  ASSERT_TRUE(server_called);
}

TEST_F(RuntimeConnectorTest, ConnectFailNoMatchingProtocol) {
  static constexpr const char* kProtocol = "test";
  static constexpr const char* kNotSupportedProtocol = "not_supported";

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto channels = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channels.is_error());

  std::atomic_bool server_called = false;
  runtime_connector_->RegisterProtocol(kProtocol, [&](fdf::Channel channel) -> zx_status_t {
    // This should not be called.
    ZX_ASSERT(false);
    return ZX_ERR_INTERNAL;
  });

  async::Executor executor(dispatcher());
  auto task =
      driver::ConnectToRuntimeProtocol<void>(*runtime_connector_client, kNotSupportedProtocol)
          .then(
              [quit_loop = QuitLoopClosure()](fpromise::result<fdf::Channel, zx_status_t>& result) {
                ASSERT_FALSE(result.is_ok());
                quit_loop();
              });
  executor.schedule_task(std::move(task));

  RunLoop();
  ASSERT_FALSE(server_called);
}

TEST_F(RuntimeConnectorTest, ConnectMultiple) {
  static constexpr const char* kProtocolA = "test1";
  static constexpr const char* kProtocolB = "test2";

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  // We will pass each end1 to Connect and verify that each callback gets the correct handle.
  auto channelsA = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channelsA.is_error());
  auto channelsB = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channelsB.is_error());

  std::atomic_bool channelA_received = false;
  runtime_connector_->RegisterProtocol(
      kProtocolA, [&, want_handle = channelsA->end1.get()](fdf::Channel channel) -> zx_status_t {
        ZX_ASSERT(channel.get() == want_handle);
        channelA_received = true;
        return ZX_OK;
      });

  std::atomic_bool channelB_received = false;
  runtime_connector_->RegisterProtocol(
      kProtocolB, [&, want_handle = channelsB->end1.get()](fdf::Channel channel) -> zx_status_t {
        ZX_ASSERT(channel.get() == want_handle);
        channelB_received = true;
        return ZX_OK;
      });

  // First try to connect to kProtocolB.
  // We don't use |driver::ConnectToRuntimeProtocol| as we want to verify the transferred
  // channel in the server callback.
  runtime_connector_client
      ->Connect(fidl::StringView::FromExternal(kProtocolB),
                fdf::wire::RuntimeProtocolServerEnd{channelsB->end1.release()})
      .ThenExactlyOnce(
          [quit_loop = QuitLoopClosure()](
              fidl::WireUnownedResult<fdf::RuntimeConnector::Connect>& result) mutable {
            ASSERT_TRUE(result.ok());
            ASSERT_FALSE(result->is_error());
            quit_loop();
          });

  RunLoop();
  ASSERT_TRUE(channelB_received);
  ASSERT_FALSE(channelA_received);
  channelB_received = false;

  // Now try to connect to kProtocolA.
  runtime_connector_client
      ->Connect(fidl::StringView::FromExternal(kProtocolA),
                fdf::wire::RuntimeProtocolServerEnd{channelsA->end1.release()})
      .ThenExactlyOnce(
          [quit_loop = QuitLoopClosure()](
              fidl::WireUnownedResult<fdf::RuntimeConnector::Connect>& result) mutable {
            ASSERT_TRUE(result.ok());
            ASSERT_FALSE(result->is_error());
            quit_loop();
          });

  RunLoop();
  ASSERT_TRUE(channelA_received);
  ASSERT_FALSE(channelB_received);
}

TEST_F(RuntimeConnectorTest, RegisterSameProtocol) {
  static constexpr const char* kProtocol = "test";

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto channels = fdf::ChannelPair::Create(0);
  ASSERT_FALSE(channels.is_error());

  runtime_connector_->RegisterProtocol(kProtocol, [&](fdf::Channel channel) -> zx_status_t {
    // This should not be called.
    ZX_ASSERT(false);
    return ZX_ERR_INTERNAL;
  });

  std::atomic_bool channel_received = false;
  runtime_connector_->RegisterProtocol(
      kProtocol, [&, want_handle = channels->end1.get()](fdf::Channel channel) -> zx_status_t {
        ZX_ASSERT(channel.get() == want_handle);
        channel_received = true;
        return ZX_OK;
      });

  runtime_connector_client
      ->Connect(fidl::StringView::FromExternal(kProtocol),
                fdf::wire::RuntimeProtocolServerEnd{channels->end1.release()})
      .ThenExactlyOnce(
          [quit_loop = QuitLoopClosure()](
              fidl::WireUnownedResult<fdf::RuntimeConnector::Connect>& result) mutable {
            ASSERT_TRUE(result.ok());
            ASSERT_FALSE(result->is_error());
            quit_loop();
          });

  RunLoop();
  ASSERT_TRUE(channel_received);
}

TEST_F(RuntimeConnectorTest, ListProtocolsNone) {
  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto endpoints = fidl::CreateEndpoints<fdf::RuntimeProtocolIterator>();
  ASSERT_FALSE(endpoints.is_error());

  auto status = runtime_connector_client->ListProtocols(std::move(endpoints->server));
  ASSERT_TRUE(status.ok());

  auto iterator = fidl::WireSharedClient<fdf::RuntimeProtocolIterator>(std::move(endpoints->client),
                                                                       dispatcher());
  iterator->GetNext().ThenExactlyOnce(
      [quit_loop = QuitLoopClosure()](
          fidl::WireUnownedResult<fdf::RuntimeProtocolIterator::GetNext>& result) mutable {
        ASSERT_TRUE(result.ok());
        ASSERT_EQ(result->protocols.count(), 0lu);
        quit_loop();
      });

  RunLoop();
}

TEST_F(RuntimeConnectorTest, ListProtocols) {
  // Register a bunch of fake protocols.
  std::set<std::string> protocols;
  for (int i = 0; i < 30; i++) {
    auto protocol = std::to_string(i);
    protocols.insert(protocol);
    runtime_connector_->RegisterProtocol(protocol,
                                         [](fdf::Channel channel) -> zx_status_t { return ZX_OK; });
  }

  auto runtime_connector_client = CreateRuntimeConnectorClient();
  ASSERT_EQ(ZX_OK, runtime_connector_client.status_value());

  auto endpoints = fidl::CreateEndpoints<fdf::RuntimeProtocolIterator>();
  ASSERT_FALSE(endpoints.is_error());

  auto status = runtime_connector_client->ListProtocols(std::move(endpoints->server));
  ASSERT_TRUE(status.ok());

  auto iterator = fidl::WireSharedClient<fdf::RuntimeProtocolIterator>(std::move(endpoints->client),
                                                                       dispatcher());
  std::set<std::string> got_protocols;
  std::atomic_bool done = false;
  do {
    iterator->GetNext().ThenExactlyOnce(
        [&, quit_loop = QuitLoopClosure()](
            fidl::WireUnownedResult<fdf::RuntimeProtocolIterator::GetNext>& result) mutable {
          ASSERT_TRUE(result.ok());
          size_t count = result->protocols.count();
          for (size_t i = 0; i < count; i++) {
            auto protocol =
                std::string(result->protocols.at(i).data(), result->protocols.at(i).size());
            ASSERT_EQ(got_protocols.find(protocol), got_protocols.end());
            got_protocols.insert(protocol);
          }
          if (count == 0) {
            done = true;
          }
          quit_loop();
        });
    RunLoop();
  } while (!done);

  ASSERT_EQ(got_protocols.size(), 30lu);
  ASSERT_EQ(protocols, got_protocols);
}
