// 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 <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>

#include <utility>

#include <zxtest/zxtest.h>

#include "src/lib/storage/vfs/cpp/tracked_remote_dir.h"

namespace {

// A Remote Directory which shuts down a dispatch loop when it is destroyed. This may be utilized to
// synchronize destruction of the remote directory with a test's dispatch loop.
class TestRemoteDir final : public fs::TrackedRemoteDir {
 public:
  TestRemoteDir(zx::channel remote, async::Loop* loop)
      : TrackedRemoteDir(std::move(remote)), loop_(loop) {}
  ~TestRemoteDir() { loop_->Shutdown(); }

 private:
  async::Loop* loop_;
};

TEST(TrackedRemoteDir, AddingTrackedDirectory) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  zx::channel server, client;
  ASSERT_EQ(ZX_OK, zx::channel::create(0u, &server, &client));

  fbl::String name = "remote-directory";
  auto dir = fbl::MakeRefCounted<fs::PseudoDir>();

  // Get attributes.
  fs::VnodeAttributes attr;
  EXPECT_EQ(ZX_OK, dir->GetAttributes(&attr));
  EXPECT_EQ(V_TYPE_DIR | V_IRUSR, attr.mode);
  EXPECT_EQ(1, attr.link_count);

  // "name" should not yet exist within the directory.
  fbl::RefPtr<fs::Vnode> node;
  EXPECT_EQ(ZX_ERR_NOT_FOUND, dir->Lookup(name, &node));

  // Add a remote directory, observe that it can be looked up.
  auto remote = fbl::MakeRefCounted<TestRemoteDir>(std::move(client), &loop);
  EXPECT_EQ(ZX_OK, remote->AddAsTrackedEntry(loop.dispatcher(), dir.get(), name));
  remote.reset();
  EXPECT_EQ(ZX_OK, dir->Lookup(name, &node));
  node.reset();

  // Forcing the remote connection to become "peer closed" causes the entry to be removed.
  server.reset();
  EXPECT_EQ(ZX_ERR_BAD_STATE, loop.Run());
  EXPECT_EQ(ZX_ERR_NOT_FOUND, dir->Lookup(name, &node));
}

TEST(TrackedRemoteDir, AddingTrackedDirectoryMultiple) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  zx::channel server, client;
  ASSERT_EQ(ZX_OK, zx::channel::create(0u, &server, &client));

  fbl::String name = "remote-directory";
  auto dir = fbl::MakeRefCounted<fs::PseudoDir>();

  auto remote = fbl::MakeRefCounted<TestRemoteDir>(std::move(client), &loop);
  EXPECT_EQ(ZX_OK, remote->AddAsTrackedEntry(loop.dispatcher(), dir.get(), name));

  // Observe that we cannot track the remote object multiple times.
  EXPECT_EQ(ZX_ERR_BAD_STATE, remote->AddAsTrackedEntry(loop.dispatcher(), dir.get(), name));

  // Observe that we cannot track the remote directory in a different
  // container.
  auto dir2 = fbl::MakeRefCounted<fs::PseudoDir>();
  EXPECT_EQ(ZX_ERR_BAD_STATE, remote->AddAsTrackedEntry(loop.dispatcher(), dir2.get(), name));

  remote.reset();

  // Forcing the remote connection to become "peer closed" causes the entry to be removed.
  server.reset();
  EXPECT_EQ(ZX_ERR_BAD_STATE, loop.Run());
  fbl::RefPtr<fs::Vnode> node;
  EXPECT_EQ(ZX_ERR_NOT_FOUND, dir->Lookup(name, &node));
}

TEST(TrackedRemoteDir, TrackAddingDifferentVnode) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  zx::channel server, client;
  ASSERT_EQ(ZX_OK, zx::channel::create(0u, &server, &client));

  auto dir = fbl::MakeRefCounted<fs::PseudoDir>();

  auto remote = fbl::MakeRefCounted<TestRemoteDir>(std::move(client), &loop);
  auto not_remote = fbl::MakeRefCounted<fs::PseudoDir>();

  // Test a subtle behavior:
  // - Add |remote| to |dir|, begin tracking the remote handle.
  // - Remove |remote| from |dir| (while still tracking).
  // - Add a different Vnode to |dir| with the same name.
  // - Close the remote connection for the still-tracked, but already-removed vnode.
  //
  // This tests that when |remote| is closed, we don't accidentally remove the "wrong" Vnode from
  // the containing pseudodirectory.
  fbl::String name = "remote-directory";
  EXPECT_EQ(ZX_OK, remote->AddAsTrackedEntry(loop.dispatcher(), dir.get(), name));
  EXPECT_EQ(ZX_OK, dir->RemoveEntry(name));
  EXPECT_EQ(ZX_OK, dir->AddEntry(name, not_remote));
  remote.reset();
  server.reset();

  EXPECT_EQ(ZX_ERR_BAD_STATE, loop.Run());
  fbl::RefPtr<fs::Vnode> node;

  // The underlying entry should NOT have been removed.
  EXPECT_EQ(ZX_OK, dir->Lookup(name, &node));
}

}  // namespace
