// 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 <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.device/cpp/wire_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <zircon/time.h>

#include <memory>

#include <fbl/ref_ptr.h>
#include <sdk/lib/device-watcher/cpp/device-watcher.h>
#include <zxtest/zxtest.h>

#include "src/lib/storage/vfs/cpp/managed_vfs.h"
#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/pseudo_file.h"
#include "src/lib/storage/vfs/cpp/service.h"

TEST(DeviceWatcherTest, Smoke) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  auto file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>(
      [](fbl::String* output) { return ZX_OK; }, [](std::string_view input) { return ZX_OK; });

  auto third = fbl::MakeRefCounted<fs::PseudoDir>();
  third->AddEntry("file", file);

  auto second = fbl::MakeRefCounted<fs::PseudoDir>();
  second->AddEntry("third", std::move(third));

  auto first = fbl::MakeRefCounted<fs::PseudoDir>();
  first->AddEntry("second", std::move(second));
  first->AddEntry("file", file);

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

  loop.StartThread();
  fs::ManagedVfs vfs(loop.dispatcher());

  vfs.ServeDirectory(first, std::move(endpoints->server));

  fbl::unique_fd dir;
  ASSERT_EQ(ZX_OK,
            fdio_fd_create(endpoints->client.TakeChannel().release(), dir.reset_and_get_address()));

  fbl::unique_fd out;
  ASSERT_EQ(ZX_OK, device_watcher::WaitForFile(dir, "file", &out));

  ASSERT_EQ(ZX_OK, device_watcher::RecursiveWaitForFile(dir, "second/third/file", &out));

  ASSERT_EQ(ZX_OK, device_watcher::RecursiveWaitForFileReadOnly(dir, "second/third/file", &out));

  sync_completion_t shutdown;

  vfs.Shutdown([&shutdown](zx_status_t status) {
    sync_completion_signal(&shutdown);
    ASSERT_EQ(status, ZX_OK);
  });
  ASSERT_EQ(sync_completion_wait(&shutdown, zx::duration::infinite().get()), ZX_OK);
}

TEST(DeviceWatcherTest, OpenInNamespace) {
  fbl::unique_fd f;
  ASSERT_EQ(device_watcher::RecursiveWaitForFileReadOnly("/dev/sys/test", &f), ZX_OK);
  ASSERT_EQ(device_watcher::RecursiveWaitForFile("/dev/sys/test", &f), ZX_OK);

  ASSERT_EQ(device_watcher::RecursiveWaitForFile("/other-test/file", &f), ZX_ERR_NOT_SUPPORTED);
}

constexpr std::string_view kTopoPath = "/dev/test/device/out";

class ControllerImpl : public fidl::testing::WireTestBase<fuchsia_device::Controller>,
                       public fs::Service {
 public:
  explicit ControllerImpl(std::string_view topo_path, async_dispatcher_t* dispatcher)
      : fs::Service([dispatcher, this](fidl::ServerEnd<fuchsia_device::Controller> server) {
          fidl::BindServer(dispatcher, std::move(server), this);
          return ZX_OK;
        }),
        topo_path_(topo_path) {}

  void GetTopologicalPath(GetTopologicalPathRequestView request,
                          GetTopologicalPathCompleter::Sync& completer) override {
    completer.ReplySuccess(fidl::StringView::FromExternal(topo_path_));
  }

  void NotImplemented_(const std::string& name, fidl::CompleterBase& completer) override {
    FAIL("Unexpected call to ControllerImpl: %s", name.c_str());
  }

 private:
  std::string topo_path_;
};

TEST(DeviceWatcherTest, WaitForDeviceTopologicalPath) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);

  auto empty_file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>(
      [](fbl::String* output) { return ZX_OK; }, [](std::string_view input) { return ZX_OK; });

  auto controller1 =
      fbl::MakeRefCounted<ControllerImpl>("/dev/test/not/the/one", loop.dispatcher());
  auto controller2 = fbl::MakeRefCounted<ControllerImpl>(kTopoPath, loop.dispatcher());

  auto first = fbl::MakeRefCounted<fs::PseudoDir>();
  first->AddEntry("file", empty_file);
  first->AddEntry("000", empty_file);
  first->AddEntry("001", controller1);
  first->AddEntry("002", controller2);
  first->AddEntry("003", empty_file);

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

  loop.StartThread();
  fs::ManagedVfs vfs(loop.dispatcher());

  vfs.ServeDirectory(first, std::move(endpoints->server));

  fbl::unique_fd dir;
  ASSERT_EQ(ZX_OK,
            fdio_fd_create(endpoints->client.TakeChannel().release(), dir.reset_and_get_address()));

  zx::status<zx::channel> status =
      device_watcher::WaitForDeviceTopologicalPath(dir, std::string(kTopoPath).c_str());
  ASSERT_TRUE(status.is_ok());

  auto ctrl_client_end = fidl::ClientEnd<fuchsia_device::Controller>(std::move(status.value()));
  fidl::WireResult result = fidl::WireCall(ctrl_client_end)->GetTopologicalPath();
  ASSERT_EQ(kTopoPath, result->value()->path.get());

  sync_completion_t shutdown;

  vfs.Shutdown([&shutdown](zx_status_t status) {
    sync_completion_signal(&shutdown);
    ASSERT_EQ(status, ZX_OK);
  });
  ASSERT_EQ(sync_completion_wait(&shutdown, zx::duration::infinite().get()), ZX_OK);
}
