// Copyright 2019 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 "device_controller_connection.h"

#include <fuchsia/io/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/zx/vmo.h>

#include <thread>

#include <fbl/auto_lock.h>
#include <zxtest/zxtest.h>

#include "connection_destroyer.h"
#include "driver_host_context.h"
#include "zx_device.h"

namespace {

TEST(DeviceControllerConnectionTestCase, Creation) {
  DriverHostContext ctx(&kAsyncLoopConfigNoAttachToCurrentThread);

  fbl::RefPtr<zx_driver> drv;
  ASSERT_OK(zx_driver::Create("test", ctx.inspect().drivers(), &drv));

  fbl::RefPtr<zx_device> dev;
  ASSERT_OK(zx_device::Create(&ctx, "test", drv.get(), &dev));

  zx::channel device_local, device_remote;
  ASSERT_OK(zx::channel::create(0, &device_local, &device_remote));

  zx::channel device_local2, device_remote2;
  ASSERT_OK(zx::channel::create(0, &device_local2, &device_remote2));

  std::unique_ptr<DeviceControllerConnection> conn;

  fidl::Client<llcpp::fuchsia::device::manager::Coordinator> client;
  client.Bind(std::move(device_remote2), ctx.loop().dispatcher());
  ASSERT_NULL(dev->conn.load());
  ASSERT_OK(DeviceControllerConnection::Create(&ctx, dev, std::move(device_remote),
                                               std::move(client), &conn));
  ASSERT_NOT_NULL(dev->conn.load());

  ASSERT_OK(DeviceControllerConnection::BeginWait(std::move(conn), ctx.loop().dispatcher()));
  ASSERT_OK(ctx.loop().RunUntilIdle());

  // Clean up memory. Connection destroyer runs asynchronously.
  {
    fbl::AutoLock lock(&ctx.api_lock());
    dev->removal_cb = [](zx_status_t) {};
    ctx.DriverManagerRemove(std::move(dev));
  }
  ASSERT_OK(ctx.loop().RunUntilIdle());
}

TEST(DeviceControllerConnectionTestCase, PeerClosedDuringReply) {
  DriverHostContext ctx(&kAsyncLoopConfigNoAttachToCurrentThread);

  fbl::RefPtr<zx_driver> drv;
  ASSERT_OK(zx_driver::Create("test", ctx.inspect().drivers(), &drv));

  fbl::RefPtr<zx_device> dev;
  ASSERT_OK(zx_device::Create(&ctx, "test", drv.get(), &dev));

  zx::channel device_local, device_remote;
  ASSERT_OK(zx::channel::create(0, &device_local, &device_remote));

  zx::channel device_local2, device_remote2;
  ASSERT_OK(zx::channel::create(0, &device_local2, &device_remote2));

  class DeviceControllerConnectionTest : public DeviceControllerConnection {
   public:
    DeviceControllerConnectionTest(
        DriverHostContext* ctx, fbl::RefPtr<zx_device> dev, zx::channel rpc,
        fidl::Client<llcpp::fuchsia::device::manager::Coordinator> coordinator_client,
        fidl::Client<::llcpp::fuchsia::device::manager::DeviceController>& local)
        : DeviceControllerConnection(ctx, std::move(dev), std::move(rpc),
                                     std::move(coordinator_client)),
          local_(local) {}

    void BindDriver(::fidl::StringView driver_path, ::zx::vmo driver,
                    BindDriverCompleter::Sync& completer) override {
      // Pretend that a device closure happened right before we began
      // processing BindDriver.  Close the other half of the channel, so the reply below will fail
      // from ZX_ERR_PEER_CLOSED.
      completer_ = completer.ToAsync();
      local_.Unbind();
    }

    void UnboundDone() {
      completer_->Reply(ZX_OK, zx::channel());

      fbl::AutoLock lock(&driver_host_context_->api_lock());
      this->dev()->removal_cb = [](zx_status_t) {};
      driver_host_context_->DriverManagerRemove(std::move(this->dev_));
    }

   private:
    fidl::Client<::llcpp::fuchsia::device::manager::DeviceController>& local_;
    std::optional<BindDriverCompleter::Async> completer_;
  };

  fidl::Client<::llcpp::fuchsia::device::manager::DeviceController> client;

  fidl::Client<llcpp::fuchsia::device::manager::Coordinator> coordinator;
  client.Bind(std::move(device_remote2), ctx.loop().dispatcher());
  std::unique_ptr<DeviceControllerConnectionTest> conn;
  conn = std::make_unique<DeviceControllerConnectionTest>(
      &ctx, std::move(dev), std::move(device_remote), std::move(coordinator), client);
  auto* conn_ref = conn.get();

  ASSERT_OK(DeviceControllerConnectionTest::BeginWait(std::move(conn), ctx.loop().dispatcher()));
  ASSERT_OK(ctx.loop().RunUntilIdle());

  bool unbound = false;
  ASSERT_OK(client.Bind(std::move(device_local), ctx.loop().dispatcher(), [&](fidl::UnbindInfo) {
    unbound = true;
    conn_ref->UnboundDone();
  }));

  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(0, 0, &vmo));
  auto result = client->BindDriver(
      ::fidl::StringView("", 1), std::move(vmo),
      [](::llcpp::fuchsia::device::manager::DeviceController::BindDriverResponse* response) {});
  ASSERT_OK(result.status());

  ASSERT_OK(ctx.loop().RunUntilIdle());
  ASSERT_TRUE(unbound);
}

// Verify we do not abort when an expected PEER_CLOSED comes in.
TEST(DeviceControllerConnectionTestCase, PeerClosed) {
  DriverHostContext ctx(&kAsyncLoopConfigNoAttachToCurrentThread);

  fbl::RefPtr<zx_driver> drv;
  ASSERT_OK(zx_driver::Create("test", ctx.inspect().drivers(), &drv));

  fbl::RefPtr<zx_device> dev;
  ASSERT_OK(zx_device::Create(&ctx, "test", drv.get(), &dev));

  zx::channel device_local, device_remote;
  ASSERT_OK(zx::channel::create(0, &device_local, &device_remote));

  zx::channel device_local2, device_remote2;
  ASSERT_OK(zx::channel::create(0, &device_local2, &device_remote2));

  fidl::Client<llcpp::fuchsia::device::manager::Coordinator> client;
  client.Bind(std::move(device_remote2), ctx.loop().dispatcher());
  std::unique_ptr<DeviceControllerConnection> conn;
  ASSERT_OK(DeviceControllerConnection::Create(&ctx, dev, std::move(device_remote),
                                               std::move(client), &conn));

  ASSERT_OK(DeviceControllerConnection::BeginWait(std::move(conn), ctx.loop().dispatcher()));
  ASSERT_OK(ctx.loop().RunUntilIdle());

  // Perform the device shutdown protocol, since otherwise the driver_host code
  // will assert, since it is unable to handle unexpected connection closures.
  {
    fbl::AutoLock lock(&ctx.api_lock());
    dev->removal_cb = [](zx_status_t) {};
    ctx.DriverManagerRemove(std::move(dev));
    device_local.reset();
  }
  ASSERT_OK(ctx.loop().RunUntilIdle());
}

TEST(DeviceControllerConnectionTestCase, UnbindHook) {
  DriverHostContext ctx(&kAsyncLoopConfigNoAttachToCurrentThread);

  fbl::RefPtr<zx_driver> drv;
  ASSERT_OK(zx_driver::Create("test", ctx.inspect().drivers(), &drv));

  fbl::RefPtr<zx_device> dev;
  ASSERT_OK(zx_device::Create(&ctx, "test", drv.get(), &dev));

  zx::channel device_local, device_remote;
  ASSERT_OK(zx::channel::create(0, &device_local, &device_remote));

  zx::channel device_local2, device_remote2;
  ASSERT_OK(zx::channel::create(0, &device_local2, &device_remote2));

  class DeviceControllerConnectionTest : public DeviceControllerConnection {
   public:
    DeviceControllerConnectionTest(
        DriverHostContext* ctx, fbl::RefPtr<zx_device> dev, zx::channel rpc,
        fidl::Client<llcpp::fuchsia::device::manager::Coordinator> coordinator_client)
        : DeviceControllerConnection(ctx, std::move(dev), std::move(rpc),
                                     std::move(coordinator_client)) {}

    void Unbind(UnbindCompleter::Sync& completer) {
      fbl::RefPtr<zx_device> dev = this->dev();
      // Set dev->flags() so that we can check that the unbind hook is called in
      // the test.
      dev->set_flag(DEV_FLAG_DEAD);
      completer.ReplySuccess();
    }
  };

  fidl::Client<llcpp::fuchsia::device::manager::Coordinator> coordinator;
  coordinator.Bind(std::move(device_remote2), ctx.loop().dispatcher());
  std::unique_ptr<DeviceControllerConnectionTest> conn;
  conn = std::make_unique<DeviceControllerConnectionTest>(
      &ctx, std::move(dev), std::move(device_remote), std::move(coordinator));
  fbl::RefPtr<zx_device> my_dev = conn->dev();
  ASSERT_OK(DeviceControllerConnectionTest::BeginWait(std::move(conn), ctx.loop().dispatcher()));
  ASSERT_OK(ctx.loop().RunUntilIdle());

  fidl::Client<::llcpp::fuchsia::device::manager::DeviceController> client;
  ASSERT_OK(client.Bind(std::move(device_local), ctx.loop().dispatcher()));

  bool unbind_successful = false;
  auto result = client->Unbind(
      [&](::llcpp::fuchsia::device::manager::DeviceController::UnbindResponse* response) {
        unbind_successful = response->result.is_response();
      });
  ASSERT_OK(result.status());

  ASSERT_OK(ctx.loop().RunUntilIdle());

  ASSERT_EQ(my_dev->flags(), DEV_FLAG_DEAD);
  ASSERT_TRUE(unbind_successful);

  client.Unbind();

  {
    fbl::AutoLock lock(&ctx.api_lock());
    my_dev->removal_cb = [](zx_status_t) {};
    ctx.DriverManagerRemove(std::move(my_dev));
  }
  ASSERT_OK(ctx.loop().RunUntilIdle());
}

}  // namespace
