// Copyright 2020 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 "inspect-manager.h"

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/namespace.h>
#include <lib/fit/single_threaded_executor.h>
#include <lib/inspect/cpp/reader.h>
#include <lib/memfs/memfs.h>
#include <sys/stat.h>

#include <fbl/unique_fd.h>
#include <fs/remote_dir.h>
#include <zxtest/zxtest.h>

#include "src/lib/fxl/strings/substitute.h"

namespace {

constexpr char kTmpfsPath[] = "/fshost-inspect-tmp";

class InspectManagerTest : public zxtest::Test {
 public:
  InspectManagerTest() : memfs_loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  void SetUp() override {
    ASSERT_EQ(memfs_loop_.StartThread(), ZX_OK);
    zx::channel memfs_root;
    ASSERT_EQ(memfs_create_filesystem(memfs_loop_.dispatcher(), &memfs_,
                                      memfs_root.reset_and_get_address()),
              ZX_OK);
    ASSERT_OK(fdio_ns_get_installed(&namespace_));
    ASSERT_OK(fdio_ns_bind(namespace_, kTmpfsPath, memfs_root.release()));
  }

  void TearDown() override {
    ASSERT_OK(fdio_ns_unbind(namespace_, kTmpfsPath));
    sync_completion_t unmounted;
    memfs_free_filesystem(memfs_, &unmounted);
    ASSERT_EQ(ZX_OK, sync_completion_wait(&unmounted, zx::duration::infinite().get()));
  }

 protected:
  fbl::RefPtr<fs::RemoteDir> GetRemoteDir() {
    zx::channel client, server;
    zx_status_t status = zx::channel::create(0, &client, &server);
    EXPECT_EQ(status, ZX_OK);
    EXPECT_EQ(ZX_OK, fdio_open(kTmpfsPath, ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_EXECUTABLE,
                               server.release()));
    return fbl::MakeRefCounted<fs::RemoteDir>(std::move(client));
  }

  fit::result<inspect::Hierarchy> ReadInspect(const inspect::Inspector& inspector) {
    fit::result<inspect::Hierarchy> hierarchy;
    fit::single_threaded_executor exec;
    exec.schedule_task(inspect::ReadFromInspector(inspector).then(
        [&](fit::result<inspect::Hierarchy>& result) { hierarchy = std::move(result); }));
    exec.run();
    return hierarchy;
  }

  void AddFile(const std::string& path, size_t content_size) {
    std::string contents(content_size, 'X');
    fbl::unique_fd fd(open(fxl::Substitute("$0/$1", kTmpfsPath, path).c_str(), O_RDWR | O_CREAT));
    ASSERT_TRUE(fd.is_valid());
    ASSERT_EQ(write(fd.get(), contents.c_str(), content_size), content_size);
  }

  void MakeDir(const std::string& path) {
    ASSERT_EQ(0, mkdir(fxl::Substitute("$0/$1", kTmpfsPath, path).c_str(), 0666));
  }

  void AssertValue(const inspect::Hierarchy& hierarchy, const std::vector<std::string>& path,
                   size_t expected, size_t other_children = 0) {
    auto file_node = hierarchy.GetByPath(path);
    EXPECT_NOT_NULL(file_node);
    ASSERT_EQ(1, file_node->node().properties().size());
    ASSERT_EQ(other_children, file_node->children().size());
    auto& size_property = file_node->node().properties()[0];
    EXPECT_EQ("size", size_property.name());
    EXPECT_EQ(expected, size_property.Get<inspect::UintPropertyValue>().value());
  }

  fdio_ns_t* namespace_;
  async::Loop memfs_loop_;
  memfs_filesystem_t* memfs_;
};

TEST_F(InspectManagerTest, ServeStats) {
  // Initialize test directory
  MakeDir("a");
  MakeDir("a/b");
  MakeDir("a/c");
  AddFile("top.txt", 12);
  AddFile("a/a.txt", 13);
  AddFile("a/b/b.txt", 14);
  AddFile("a/c/c.txt", 15);
  AddFile("a/c/d.txt", 16);

  // Serve inspect stats.
  auto inspect_manager = devmgr::InspectManager();
  auto remote_dir = GetRemoteDir();
  inspect_manager.ServeStats("test_dir", remote_dir);

  //// Read inspect
  auto result = ReadInspect(inspect_manager.inspector());
  ASSERT_TRUE(result.is_ok());
  auto& hierarchy = result.value();

  // Assert root
  ASSERT_EQ(1, hierarchy.children().size());
  ASSERT_EQ(0, hierarchy.node().properties().size());

  // Assert all size values.
  AssertValue(hierarchy, {"test_dir_stats", "test_dir"}, 70, 2);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "top.txt"}, 12);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a"}, 58, 3);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "a.txt"}, 13);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "b"}, 14, 1);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "b", "b.txt"}, 14);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "c"}, 31, 2);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "c", "c.txt"}, 15);
  AssertValue(hierarchy, {"test_dir_stats", "test_dir", "a", "c", "d.txt"}, 16);
}

TEST_F(InspectManagerTest, DirectoryEntryIteratorGetNext) {
  MakeDir("iterator-test");
  for (int64_t i = 0; i < 5000; i++) {
    if (i % 2 == 0) {
      MakeDir(fxl::Substitute("/iterator-test/dir$0", std::to_string(i)));
    } else {
      AddFile(fxl::Substitute("/iterator-test/file$0", std::to_string(i)), 10);
    }
  }
  zx::channel root, server;
  zx_status_t status = zx::channel::create(0, &root, &server);
  ASSERT_EQ(status, ZX_OK);
  ASSERT_EQ(ZX_OK,
            fdio_open(kTmpfsPath, ZX_FS_RIGHT_READABLE | ZX_FS_RIGHT_EXECUTABLE, server.release()));
  fidl::ClientEnd<::llcpp::fuchsia::io::Node> test_dir_chan;
  status = devmgr::OpenNode(zx::unowned_channel(root), "/iterator-test", S_IFDIR, &test_dir_chan);
  ASSERT_EQ(status, ZX_OK);

  // The opened node must be a directory because of the |MakeDir| call above.
  fidl::ClientEnd<::llcpp::fuchsia::io::Directory> test_dir(test_dir_chan.TakeChannel());
  auto iterator = devmgr::DirectoryEntriesIterator(std::move(test_dir));
  int64_t found = 0;
  while (auto entry = iterator.GetNext()) {
    if (entry->name.find("dir") == 0) {
      EXPECT_EQ(entry->size, 0);
      EXPECT_TRUE(entry->is_dir);
    } else {
      EXPECT_EQ(entry->name.find("file"), 0);
      EXPECT_EQ(entry->size, 10);
      EXPECT_FALSE(entry->is_dir);
    }
    EXPECT_TRUE(entry->node.is_valid());
    found += 1;
  }
  EXPECT_EQ(found, 5000);
}

}  // namespace
