// Copyright 2018 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 <fs/pseudo-dir.h>
#include <fs/pseudo-file.h>
#include <fs/remote-dir.h>
#include <fs/synchronous-vfs.h>
#include <fuchsia/device/manager/cpp/fidl.h>
#include <fuchsia/kernel/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
#include <fuchsia/virtualconsole/cpp/fidl.h>
#include <lib/fdio/spawn.h>
#include <zircon/syscalls/object.h>

#include "garnet/bin/appmgr/component_controller_impl.h"
#include "garnet/bin/appmgr/util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lib/fsl/handles/object_info.h"
#include "lib/gtest/real_loop_fixture.h"
#include "src/lib/fxl/log_settings.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/split_string.h"

namespace component {
namespace {

using fuchsia::sys::ServiceList;
using fuchsia::sys::ServiceListPtr;
using fuchsia::sys::TerminationReason;

template <typename T>
class ComponentContainerImpl : public ComponentContainer<T> {
 public:
  size_t ComponentCount() { return components_.size(); }
  const std::string koid() { return "5342"; }

  void AddComponent(std::unique_ptr<T> component);

  std::shared_ptr<T> ExtractComponent(T* controller) override;

 private:
  std::unordered_map<T*, std::shared_ptr<T>> components_;
};

template <typename T>
void ComponentContainerImpl<T>::AddComponent(std::unique_ptr<T> component) {
  auto key = component.get();
  components_.emplace(key, std::move(component));
}

template <typename T>
std::shared_ptr<T> ComponentContainerImpl<T>::ExtractComponent(T* controller) {
  auto it = components_.find(controller);
  if (it == components_.end()) {
    return nullptr;
  }
  auto component = std::move(it->second);

  components_.erase(it);
  return component;
}

// Get a list of the default service entries that exist in every namespace.
// See |Namespace::Namespace| constructor.
std::vector<std::string> GetDefaultNamespaceServiceEntries() {
  return std::vector<std::string>{
      ".",
      Namespace::Launcher::Name_,
      fuchsia::device::manager::Administrator::Name_,
      fuchsia::device::manager::DebugDumper::Name_,
      fuchsia::kernel::DebugBroker::Name_,
      fuchsia::process::Launcher::Name_,
      fuchsia::process::Resolver::Name_,
      fuchsia::scheduler::ProfileProvider::Name_,
      fuchsia::sys::Environment::Name_,
      fuchsia::virtualconsole::SessionManager::Name_,
  };
}

// Create a new Namespace that contains the default services available to all
// namespaces, plus the given |service_names|. The resulting object is useful
// for listing its service names but not much else.
fxl::RefPtr<Namespace> CreateFakeNamespace(
    const std::vector<const char*>& extra_service_names) {
  ServiceListPtr service_list(new ServiceList());
  for (auto& service : extra_service_names) {
    service_list->names.push_back(service);
  }
  return fxl::MakeRefCounted<Namespace>(nullptr, nullptr,
                                        std::move(service_list), nullptr);
}

std::vector<std::string> SplitPath(const std::string& path) {
  return fxl::SplitStringCopy(path, "/",
                              fxl::WhiteSpaceHandling::kKeepWhitespace,
                              fxl::SplitResult::kSplitWantAll);
}

bool PathExists(const fbl::RefPtr<fs::PseudoDir>& hub_dir, std::string path,
                fbl::RefPtr<fs::Vnode>* out = nullptr) {
  auto tokens = SplitPath(path);
  auto ntokens = tokens.size();
  fbl::RefPtr<fs::Vnode> dir = hub_dir;
  fbl::RefPtr<fs::Vnode> pdir;
  for (size_t i = 0; i < ntokens; i++) {
    auto token = tokens[i];
    pdir = dir;
    if (pdir->Lookup(&dir, token) != ZX_OK) {
      return false;
    }
  }
  if (out != nullptr) {
    *out = dir;
  }
  return true;
}

// Get a list of names of the entries in a directory. This will generally
// include at least "." (i.e. the current directory).
std::vector<std::string> GetDirectoryEntries(fbl::RefPtr<fs::Vnode> dir) {
  std::vector<std::string> entry_names{};
  // Arbitrary size.
  uint8_t buffer[4096];

  fs::vdircookie_t cookie{};
  // Actual number of bytes read into the buffer.
  size_t real_len = 0;
  while (dir->Readdir(&cookie, buffer, sizeof(buffer), &real_len) == ZX_OK &&
         real_len > 0) {
    size_t offset = 0;
    while (offset < real_len) {
      auto dir_entry = reinterpret_cast<vdirent_t*>(buffer + offset);
      size_t entry_size = sizeof(vdirent_t) + dir_entry->size;
      std::string name(dir_entry->name, dir_entry->size);
      entry_names.push_back(name);
      offset += entry_size;
    }
  }
  return entry_names;
}

// Assert that the hub for the given component has "in", "in/svc", default
// services, and the given extra service names.
void AssertHubHasIncomingServices(
    const ComponentControllerBase* component,
    const std::vector<std::string>& extra_service_names) {
  ASSERT_TRUE(PathExists(component->hub_dir(), "in"));
  fbl::RefPtr<fs::Vnode> in_svc_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "in/svc", &in_svc_dir));
  for (auto& service : extra_service_names) {
    EXPECT_TRUE(PathExists(component->hub_dir(), "in/svc/" + service));
  }

  // Default entries from namespace, plus the two we added.
  auto expected_entries = GetDefaultNamespaceServiceEntries();
  expected_entries.insert(expected_entries.end(), extra_service_names.begin(),
                          extra_service_names.end());
  EXPECT_THAT(GetDirectoryEntries(in_svc_dir),
              ::testing::UnorderedElementsAreArray(expected_entries));
}

typedef ComponentContainerImpl<ComponentControllerImpl> FakeRealm;
typedef ComponentContainerImpl<ComponentBridge> FakeRunner;

class ComponentControllerTest : public gtest::RealLoopFixture {
 public:
  void SetUp() override {
    gtest::RealLoopFixture::SetUp();
    vfs_.SetDispatcher(async_get_default_dispatcher());

    // create child job
    zx_status_t status = zx::job::create(*zx::job::default_job(), 0u, &job_);
    ASSERT_EQ(status, ZX_OK);

    // create process
    const char* argv[] = {"sh", NULL};
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    status = fdio_spawn_etc(job_.get(), FDIO_SPAWN_CLONE_ALL, "/boot/bin/sh",
                            argv, NULL, 0, NULL,
                            process_.reset_and_get_address(), err_msg);
    ASSERT_EQ(status, ZX_OK) << err_msg;
    process_koid_ = std::to_string(fsl::GetKoid(process_.get()));
  }

  void TearDown() override {
    if (job_) {
      job_.kill();
    }
    gtest::RealLoopFixture::TearDown();
  }

 protected:
  std::unique_ptr<ComponentControllerImpl> CreateComponent(
      fuchsia::sys::ComponentControllerPtr& controller,
      zx::channel export_dir = zx::channel(),
      fxl::RefPtr<Namespace> ns = CreateFakeNamespace({})) {
    // job_ is used later in a test to check the job-id, so we need to make a
    // clone of it to pass into std::move
    zx::job job_clone;
    zx_status_t status = job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &job_clone);
    if (status != ZX_OK)
      return NULL;
    return std::make_unique<ComponentControllerImpl>(
        controller.NewRequest(), &realm_, std::move(job_clone),
        std::move(process_), "test-url", "test-arg", "test-label", ns,
        std::move(export_dir), zx::channel(),
        MakeForwardingTerminationCallback());
  }

  FakeRealm realm_;
  zx::job job_;
  std::string process_koid_;
  zx::process process_;
  fs::SynchronousVfs vfs_;
};

class ComponentBridgeTest : public gtest::RealLoopFixture,
                            public fuchsia::sys::ComponentController {
 public:
  ComponentBridgeTest()
      : binding_(this), binding_error_handler_called_(false) {}
  void SetUp() override {
    gtest::RealLoopFixture::SetUp();
    vfs_.SetDispatcher(async_get_default_dispatcher());
    binding_.Bind(remote_controller_.NewRequest());
    binding_.set_error_handler([this](zx_status_t status) {
      binding_error_handler_called_ = true;
      Kill();
    });
  }

  void Kill() override {
    SendReturnCode();
    binding_.Unbind();
  }

  void Detach() override { binding_.set_error_handler(nullptr); }

 protected:
  std::unique_ptr<ComponentBridge> CreateComponentBridge(
      fuchsia::sys::ComponentControllerPtr& controller,
      zx::channel export_dir = zx::channel(),
      fxl::RefPtr<Namespace> ns = CreateFakeNamespace({})) {
    // only allow creation of one component.
    if (!remote_controller_) {
      return nullptr;
    }
    auto component = std::make_unique<ComponentBridge>(
        controller.NewRequest(), std::move(remote_controller_), &runner_,
        "test-url", "test-arg", "test-label", "1", ns, std::move(export_dir),
        zx::channel(), MakeForwardingTerminationCallback());
    component->SetParentJobId(runner_.koid());
    return component;
  }

  void SetReturnCode(int64_t errcode) { errcode_ = errcode; }

  void SendReady() { binding_.events().OnDirectoryReady(); }

  void SendReturnCode() {
    binding_.events().OnTerminated(errcode_, TerminationReason::EXITED);
  }

  FakeRunner runner_;
  ::fidl::Binding<fuchsia::sys::ComponentController> binding_;
  fuchsia::sys::ComponentControllerPtr remote_controller_;
  fs::SynchronousVfs vfs_;
  int64_t errcode_ = 1;

  bool binding_error_handler_called_;
};

fbl::String get_value(const fbl::RefPtr<fs::PseudoDir>& hub_dir,
                      std::string path) {
  auto tokens = SplitPath(path);
  auto ntokens = tokens.size();
  fbl::RefPtr<fs::Vnode> node = hub_dir;
  fbl::RefPtr<fs::Vnode> pdir;
  for (size_t i = 0; i < ntokens; i++) {
    auto token = tokens[i];
    pdir = node;
    if (pdir->Lookup(&node, token) != ZX_OK) {
      EXPECT_FALSE(true) << token << " not found";
      return "";
    }
  }
  fbl::RefPtr<fs::Vnode> file;
  if (node->Open(ZX_FS_RIGHT_READABLE, &file) != ZX_OK) {
    EXPECT_FALSE(true) << "cannot open: " << path;
    return "";
  }
  char buf[1024];
  size_t read_len;
  file->Read(buf, sizeof(buf), 0, &read_len);
  return fbl::String(buf, read_len);
}

TEST_F(ComponentControllerTest, CreateAndKill) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponent(component_ptr);
  auto hub_info = component->HubInfo();

  EXPECT_EQ(hub_info.label(), "test-label");
  EXPECT_EQ(hub_info.koid(), process_koid_);

  ASSERT_EQ(realm_.ComponentCount(), 0u);
  realm_.AddComponent(std::move(component));

  ASSERT_EQ(realm_.ComponentCount(), 1u);

  bool wait = false;
  int64_t return_code;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t err,
                                            TerminationReason reason) {
    return_code = err;
    termination_reason = reason;
    wait = true;
  };
  component_ptr->Kill();
  EXPECT_TRUE(RunLoopUntil([&wait] { return wait; }));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  // TODO(cpu) FLK-130: EXPECT_EQ(ZX_TASK_RETCODE_SYSCALL_KILL, return_code);
  // is flaky.
  EXPECT_EQ(TerminationReason::EXITED, termination_reason);
  EXPECT_EQ(realm_.ComponentCount(), 0u);
}

TEST_F(ComponentControllerTest, CreateAndDeleteWithoutKilling) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  int64_t return_code = 0;
  TerminationReason termination_reason = TerminationReason::INTERNAL_ERROR;

  auto component = CreateComponent(component_ptr);
  auto* component_to_remove = component.get();
  realm_.AddComponent(std::move(component));
  component_ptr.events().OnTerminated = [&](int64_t err,
                                            TerminationReason reason) {
    return_code = err;
    termination_reason = reason;
  };
  realm_.ExtractComponent(component_to_remove);

  EXPECT_TRUE(RunLoopUntil([&return_code] { return return_code; }));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(-1, return_code);
  EXPECT_EQ(TerminationReason::UNKNOWN, termination_reason);
  EXPECT_EQ(realm_.ComponentCount(), 0u);
}

TEST_F(ComponentControllerTest, ControllerScope) {
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponent(component_ptr);
    realm_.AddComponent(std::move(component));

    ASSERT_EQ(realm_.ComponentCount(), 1u);
  }
  EXPECT_TRUE(RunLoopUntil([this]() { return realm_.ComponentCount() == 0; }));
}

TEST_F(ComponentControllerTest, DetachController) {
  auto log_settings = fxl::GetLogSettings();
  log_settings.min_log_level = -2;
  fxl::SetLogSettings(log_settings);
  bool wait = false;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponent(component_ptr);
    component_ptr.events().OnTerminated =
        [&](int64_t return_code, TerminationReason termination_reason) {
          FXL_LOG(ERROR) << "OnTerminated called: " << return_code
                         << ", : " << static_cast<uint32_t>(termination_reason);
          wait = true;
        };
    realm_.AddComponent(std::move(component));

    ASSERT_EQ(realm_.ComponentCount(), 1u);

    // detach controller before it goes out of scope and then test that our
    // component did not die.
    component_ptr->Detach();
    RunLoopUntilIdle();
    EXPECT_FALSE(wait)
        << "Please please please report logs from this failure to FLK-168.";
  }

  // make sure all messages are processed if Kill was called.
  RunLoopUntilIdle();
  EXPECT_FALSE(wait)
      << "Please please please report logs from this failure to FLK-168.";
  EXPECT_EQ(realm_.ComponentCount(), 1u)
      << "Please please please report logs from this failure to FLK-168.";
}

TEST_F(ComponentControllerTest, Hub) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  auto component = CreateComponent(component_ptr, std::move(export_dir_req));

  bool ready = false;
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  RunLoopUntil([&ready] { return ready; });

  EXPECT_TRUE(PathExists(component->hub_dir(), "out"));
  EXPECT_STREQ(get_value(component->hub_dir(), "name").c_str(), "test-label");
  EXPECT_STREQ(get_value(component->hub_dir(), "args").c_str(), "test-arg");
  EXPECT_STREQ(get_value(component->hub_dir(), "job-id").c_str(),
               std::to_string(fsl::GetKoid(job_.get())).c_str());
  EXPECT_STREQ(get_value(component->hub_dir(), "url").c_str(), "test-url");
  EXPECT_STREQ(get_value(component->hub_dir(), "process-id").c_str(),
               process_koid_.c_str());

  // "in", "in/svc", and default services should exist.
  AssertHubHasIncomingServices(component.get(), {});

  fbl::RefPtr<fs::Vnode> out_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "out", &out_dir));
  ASSERT_TRUE(out_dir->IsRemote());
}

TEST_F(ComponentControllerTest, HubWithIncomingServices) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  fxl::RefPtr<Namespace> ns = CreateFakeNamespace({"service_a", "service_b"});

  auto component =
      CreateComponent(component_ptr, std::move(export_dir_req), ns);

  bool ready = false;
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  RunLoopUntil([&ready] { return ready; });

  AssertHubHasIncomingServices(component.get(), {"service_a", "service_b"});
}

TEST_F(ComponentBridgeTest, CreateAndKill) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  auto hub_info = component->HubInfo();

  EXPECT_EQ(hub_info.label(), "test-label");

  ASSERT_EQ(runner_.ComponentCount(), 0u);
  runner_.AddComponent(std::move(component));

  ASSERT_EQ(runner_.ComponentCount(), 1u);

  bool wait = false;
  bool ready = false;
  int64_t retval;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&wait, &retval, &termination_reason](
                                            int64_t errcode,
                                            TerminationReason tr) {
    wait = true;
    retval = errcode;
    termination_reason = tr;
  };
  component_ptr.events().OnDirectoryReady = [&ready] { ready = true; };
  int64_t expected_retval = (1L << 60);
  SendReady();
  SetReturnCode(expected_retval);
  component_ptr->Kill();
  EXPECT_TRUE(RunLoopUntil([&wait] { return wait; }));
  EXPECT_TRUE(ready);
  EXPECT_EQ(expected_retval, retval);
  EXPECT_EQ(TerminationReason::EXITED, termination_reason);

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, CreateAndDeleteWithoutKilling) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  auto* component_to_remove = component.get();
  component->SetTerminationReason(TerminationReason::INTERNAL_ERROR);
  runner_.AddComponent(std::move(component));

  bool terminated = false;
  int64_t retval = 0;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t errcode,
                                            TerminationReason tr) {
    terminated = true;
    retval = errcode;
    termination_reason = tr;
  };
  // Component controller called OnTerminated before the component is destroyed,
  // so we expect the value set above (INTERNAL_ERROR).
  runner_.ExtractComponent(component_to_remove);
  EXPECT_TRUE(RunLoopUntil([&terminated] { return terminated; }));
  EXPECT_EQ(-1, retval);
  EXPECT_EQ(TerminationReason::INTERNAL_ERROR, termination_reason);

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, RemoteComponentDied) {
  fuchsia::sys::ComponentControllerPtr component_ptr;
  auto component = CreateComponentBridge(component_ptr);
  component->SetTerminationReason(TerminationReason::EXITED);
  runner_.AddComponent(std::move(component));

  bool terminated = false;
  int64_t retval = 0;
  TerminationReason termination_reason;
  component_ptr.events().OnTerminated = [&](int64_t errcode,
                                            TerminationReason tr) {
    terminated = true;
    retval = errcode;
    termination_reason = tr;
  };
  // Even though the termination reason was set above, unbinding and closing the
  // channel will cause the bridge to return UNKNOWN>.
  binding_.Unbind();
  EXPECT_TRUE(RunLoopUntil([&terminated] { return terminated; }));
  EXPECT_EQ(-1, retval);
  EXPECT_EQ(TerminationReason::UNKNOWN, termination_reason);
  EXPECT_EQ(0u, runner_.ComponentCount());

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, ControllerScope) {
  bool wait = false;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponentBridge(component_ptr);
    component->OnTerminated(
        [&wait](int64_t return_code, TerminationReason termination_reason) {
          wait = true;
        });
    runner_.AddComponent(std::move(component));
    ASSERT_EQ(runner_.ComponentCount(), 1u);
  }
  EXPECT_TRUE(RunLoopUntil([&wait] { return wait; }));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, DetachController) {
  bool wait = false;
  ComponentBridge* component_bridge_ptr;
  {
    fuchsia::sys::ComponentControllerPtr component_ptr;
    auto component = CreateComponentBridge(component_ptr);
    component_bridge_ptr = component.get();
    runner_.AddComponent(std::move(component));

    ASSERT_EQ(runner_.ComponentCount(), 1u);

    // detach controller before it goes out of scope and then test that our
    // component did not die.
    component_ptr->Detach();
    RunLoopUntilIdle();
  }

  // make sure all messages are processed if Kill was called.
  RunLoopUntilIdle();
  ASSERT_FALSE(wait);
  EXPECT_EQ(runner_.ComponentCount(), 1u);

  // bridge should be still connected, kill that to see if we are able to kill
  // real component.
  component_bridge_ptr->OnTerminated(
      [&wait](int64_t return_code, TerminationReason termination_reason) {
        wait = true;
      });
  component_bridge_ptr->Kill();
  EXPECT_TRUE(RunLoopUntil([&wait] { return wait; }));

  // make sure all messages are processed after wait was called
  RunLoopUntilIdle();
  EXPECT_EQ(runner_.ComponentCount(), 0u);
}

TEST_F(ComponentBridgeTest, Hub) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  auto component =
      CreateComponentBridge(component_ptr, std::move(export_dir_req));

  RunLoopUntil(
      [this, &component] { return PathExists(component->hub_dir(), "out"); });

  EXPECT_STREQ(get_value(component->hub_dir(), "name").c_str(), "test-label");
  EXPECT_STREQ(get_value(component->hub_dir(), "args").c_str(), "test-arg");
  EXPECT_STREQ(get_value(component->hub_dir(), "job-id").c_str(),
               runner_.koid().c_str());
  EXPECT_STREQ(get_value(component->hub_dir(), "url").c_str(), "test-url");
  fbl::RefPtr<fs::Vnode> out_dir;
  ASSERT_TRUE(PathExists(component->hub_dir(), "out", &out_dir));
  ASSERT_TRUE(out_dir->IsRemote());

  // "in", "in/svc", and default services should exist.
  AssertHubHasIncomingServices(component.get(), {});
}

TEST_F(ComponentBridgeTest, HubWithIncomingServices) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);
  vfs_.ServeDirectory(fbl::MakeRefCounted<fs::PseudoDir>(),
                      std::move(export_dir));

  fuchsia::sys::ComponentControllerPtr component_ptr;

  fxl::RefPtr<Namespace> ns = CreateFakeNamespace({"service_a", "service_b"});

  auto component =
      CreateComponentBridge(component_ptr, std::move(export_dir_req), ns);

  RunLoopUntil(
      [this, &component] { return PathExists(component->hub_dir(), "out"); });

  AssertHubHasIncomingServices(component.get(), {"service_a", "service_b"});
}

TEST_F(ComponentBridgeTest, BindingErrorHandler) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);

  fuchsia::sys::ComponentControllerPtr component_ptr;
  {
    // let it go out of scope, that should trigger binding error handler.
    auto component =
        CreateComponentBridge(component_ptr, std::move(export_dir_req));
  }
  EXPECT_TRUE(RunLoopUntil([this] { return !binding_.is_bound(); }));
  EXPECT_TRUE(binding_error_handler_called_);
}

TEST_F(ComponentBridgeTest, BindingErrorHandlerWhenDetached) {
  zx::channel export_dir, export_dir_req;
  ASSERT_EQ(zx::channel::create(0, &export_dir, &export_dir_req), ZX_OK);

  fuchsia::sys::ComponentControllerPtr component_ptr;
  {
    // let it go out of scope, that should trigger binding error handler.
    auto component =
        CreateComponentBridge(component_ptr, std::move(export_dir_req));
    component_ptr->Detach();
    RunLoopUntilIdle();
  }
  EXPECT_TRUE(RunLoopUntil([this] { return !binding_.is_bound(); }));
  EXPECT_TRUE(binding_error_handler_called_);
}

TEST(ComponentControllerUnitTest, GetDirectoryEntries) {
  auto dir = fbl::AdoptRef<fs::PseudoDir>(new fs::PseudoDir());
  auto subdir = fbl::AdoptRef<fs::Vnode>(new fs::PseudoDir());
  auto file1 = fbl::AdoptRef<fs::Vnode>(new fs::UnbufferedPseudoFile());
  auto file2 = fbl::AdoptRef<fs::Vnode>(new fs::UnbufferedPseudoFile());

  // add entries
  EXPECT_EQ(ZX_OK, dir->AddEntry("subdir", subdir));
  EXPECT_EQ(ZX_OK, dir->AddEntry("file1", file1));
  EXPECT_EQ(ZX_OK, dir->AddEntry("file2", file2));

  const std::vector<std::string> entries = GetDirectoryEntries(dir);
  EXPECT_THAT(entries, ::testing::ElementsAre(".", "subdir", "file1", "file2"));
}

}  // namespace
}  // namespace component
