// 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 <fuchsia/device/manager/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl-async/cpp/bind.h>

#include <ddk/driver.h>
#include <zxtest/zxtest.h>

#include "devhost.h"
#include "zx-device.h"

namespace {

class FakeCoordinator : public ::llcpp::fuchsia::device::manager::Coordinator::Interface {
 public:
  zx_status_t Connect(async_dispatcher_t* dispatcher, zx::channel request) {
    return fidl::Bind(dispatcher, std::move(request), this);
  }

  void AddDevice(::zx::channel coordinator, ::zx::channel device_controller,
                 ::fidl::VectorView<uint64_t> props, ::fidl::StringView name, uint32_t protocol_id,
                 ::fidl::StringView driver_path, ::fidl::StringView args,
                 llcpp::fuchsia::device::manager::AddDeviceConfig device_add_config, bool has_init,
                 ::zx::channel client_remote, AddDeviceCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_AddDevice_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void ScheduleRemove(bool unbind_self, ScheduleRemoveCompleter::Sync completer) override {}
  void AddCompositeDevice(::fidl::StringView name,
                          llcpp::fuchsia::device::manager::CompositeDeviceDescriptor comp_desc,
                          AddCompositeDeviceCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_AddCompositeDevice_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void PublishMetadata(::fidl::StringView device_path, uint32_t key,
                       ::fidl::VectorView<uint8_t> data,
                       PublishMetadataCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_PublishMetadata_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void AddDeviceInvisible(::zx::channel coordinator, ::zx::channel device_controller,
                          ::fidl::VectorView<uint64_t> props, ::fidl::StringView name,
                          uint32_t protocol_id, ::fidl::StringView driver_path,
                          ::fidl::StringView args, bool has_init, ::zx::channel client_remote,
                          AddDeviceInvisibleCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_AddDeviceInvisible_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void MakeVisible(MakeVisibleCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_MakeVisible_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void BindDevice(::fidl::StringView driver_path, BindDeviceCompleter::Sync completer) override {
    bind_count_++;
    llcpp::fuchsia::device::manager::Coordinator_BindDevice_Result response;
    zx_status_t status = ZX_OK;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void GetTopologicalPath(GetTopologicalPathCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_GetTopologicalPath_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void LoadFirmware(::fidl::StringView fw_path, LoadFirmwareCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_LoadFirmware_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void GetMetadata(uint32_t key, GetMetadataCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_GetMetadata_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void GetMetadataSize(uint32_t key, GetMetadataSizeCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_GetMetadataSize_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void AddMetadata(uint32_t key, ::fidl::VectorView<uint8_t> data,
                   AddMetadataCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_AddMetadata_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void ScheduleUnbindChildren(ScheduleUnbindChildrenCompleter::Sync completer) override {}
  void RunCompatibilityTests(int64_t hook_wait_time,
                             RunCompatibilityTestsCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_RunCompatibilityTests_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }
  void DirectoryWatch(uint32_t mask, uint32_t options, ::zx::channel watcher,
                      DirectoryWatchCompleter::Sync completer) override {
    llcpp::fuchsia::device::manager::Coordinator_DirectoryWatch_Result response;
    zx_status_t status = ZX_ERR_NOT_SUPPORTED;
    response.set_err(&status);
    completer.Reply(std::move(response));
  }

  uint32_t bind_count_ = 0;
  uint32_t unbind_reply_count_ = 0;
};

class CoreTest : public zxtest::Test {
 protected:
  CoreTest() : loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
    loop_.StartThread("devhost-test-loop");
  }

  void Connect(zx::channel* out) {
    zx::channel local, remote;
    ASSERT_OK(zx::channel::create(0, &local, &remote));
    ASSERT_OK(coordinator_.Connect(loop_.dispatcher(), std::move(remote)));
    *out = std::move(local);
  }

  // This simulates receiving an unbind and remove request from the devcoordinator.
  void UnbindDevice(fbl::RefPtr<zx_device> dev) {
    devmgr::ApiAutoLock lock;
    devmgr::devhost_device_unbind(dev);
    // devhost_device_complete_removal() will drop the device reference added by device_add().
    // Since we never called device_add(), we should increment the reference count here.
    fbl::RefPtr<zx_device_t> dev_add_ref(dev.get());
    __UNUSED auto ptr = fbl::ExportToRawPtr(&dev_add_ref);
    devmgr::devhost_device_complete_removal(dev);
  }

  async::Loop loop_;
  FakeCoordinator coordinator_;
};

TEST_F(CoreTest, RebindNoChildren) {
  fbl::RefPtr<zx_device> dev;
  ASSERT_OK(zx_device::Create(&dev));

  zx_protocol_device_t ops = {};
  dev->ops = &ops;

  zx::channel rpc;
  ASSERT_NO_FATAL_FAILURES(Connect(&rpc));
  dev->coordinator_rpc = zx::unowned(rpc);

  EXPECT_EQ(device_rebind(dev.get()), ZX_OK);
  EXPECT_EQ(coordinator_.bind_count_, 1);

  dev->flags |= DEV_FLAG_DEAD;
}

TEST_F(CoreTest, RebindHasOneChild) {
  {
    uint32_t unbind_count = 0;
    fbl::RefPtr<zx_device> parent;

    zx::channel rpc;
    ASSERT_NO_FATAL_FAILURES(Connect(&rpc));

    zx_protocol_device_t ops = {};
    ops.unbind = [](void* ctx) { *static_cast<uint32_t*>(ctx) += 1; };

    ASSERT_OK(zx_device::Create(&parent));
    parent->ops = &ops;
    parent->ctx = &unbind_count;
    parent->coordinator_rpc = zx::unowned(rpc);
    {
      fbl::RefPtr<zx_device> child;
      ASSERT_OK(zx_device::Create(&child));
      child->ops = &ops;
      child->ctx = &unbind_count;
      child->rpc = zx::unowned(rpc);
      parent->children.push_back(child.get());
      child->parent = parent;

      EXPECT_EQ(device_rebind(parent.get()), ZX_OK);
      EXPECT_EQ(coordinator_.bind_count_, 0);
      ASSERT_NO_FATAL_FAILURES(UnbindDevice(child));
      EXPECT_EQ(unbind_count, 1);

      child->flags |= DEV_FLAG_DEAD;
    }
    parent->flags |= DEV_FLAG_DEAD;
  }
  EXPECT_EQ(coordinator_.bind_count_, 1);
}

TEST_F(CoreTest, RebindHasMultipleChildren) {
  {
    uint32_t unbind_count = 0;
    fbl::RefPtr<zx_device> parent;

    zx::channel rpc;
    ASSERT_NO_FATAL_FAILURES(Connect(&rpc));

    zx_protocol_device_t ops = {};
    ops.unbind = [](void* ctx) { *static_cast<uint32_t*>(ctx) += 1; };

    ASSERT_OK(zx_device::Create(&parent));
    parent->ops = &ops;
    parent->ctx = &unbind_count;
    parent->coordinator_rpc = zx::unowned(rpc);
    {
      std::array<fbl::RefPtr<zx_device>, 5> children;
      for (auto& child : children) {
        ASSERT_OK(zx_device::Create(&child));
        child->ops = &ops;
        child->ctx = &unbind_count;
        child->rpc = zx::unowned(rpc);
        parent->children.push_back(child.get());
        child->parent = parent;
      }

      EXPECT_EQ(device_rebind(parent.get()), ZX_OK);

      for (auto& child : children) {
        EXPECT_EQ(coordinator_.bind_count_, 0);
        ASSERT_NO_FATAL_FAILURES(UnbindDevice(child));
      }

      EXPECT_EQ(unbind_count, children.size());

      for (auto& child : children) {
        child->flags |= DEV_FLAG_DEAD;
      }
    }
    parent->flags |= DEV_FLAG_DEAD;
  }
  EXPECT_EQ(coordinator_.bind_count_, 1);
}

}  // namespace
