// 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 <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <fidl/fuchsia.kernel/cpp/wire.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 <lib/fdio/fdio.h>
#include <lib/memfs/memfs.h>
#include <lib/service/llcpp/service.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <threads.h>
#include <unistd.h>
#include <zircon/errors.h>
#include <zircon/processargs.h>
#include <zircon/rights.h>
#include <zircon/syscalls.h>

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

#include "src/storage/memfs/memfs.h"
#include "src/storage/memfs/vnode_dir.h"

namespace {

namespace fio = fuchsia_io;

// These are rights that are common to the various rights checks below.
const uint32_t kCommonExpectedRights =
    ZX_RIGHTS_BASIC | ZX_RIGHT_MAP | ZX_RIGHT_READ | ZX_RIGHT_GET_PROPERTY;

zx_rights_t get_rights(const zx::object_base& handle) {
  zx_info_handle_basic_t info;
  zx_status_t status = handle.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.rights : ZX_RIGHT_NONE;
}

// The following sequence of events must occur to terminate cleanly:
// 1) Invoke "vfs.Shutdown", passing a closure.
// 2) Wait for the closure to be invoked, and for |completion| to be signalled. This implies
// that Shutdown no longer relies on the dispatch loop, nor will it attempt to continue
// accessing |completion|.
// 3) Shutdown the dispatch loop (happens automatically when the async::Loop goes out of scope).
//
// If the dispatch loop is terminated too before the vfs shutdown task completes, it may see
// "ZX_ERR_CANCELED" posted to the "vfs.Shutdown" closure instead.
void shutdown_vfs(std::unique_ptr<memfs::Memfs> vfs) {
  sync_completion_t completion;
  vfs->Shutdown([&completion](zx_status_t status) {
    EXPECT_OK(status);
    sync_completion_signal(&completion);
  });
  sync_completion_wait(&completion, zx::sec(5).get());
}

TEST(VmofileTests, test_vmofile_basic) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  async_dispatcher_t* dispatcher = loop.dispatcher();

  zx::status directory_endpoints = fidl::CreateEndpoints<fio::Directory>();
  ASSERT_OK(directory_endpoints.status_value());

  std::unique_ptr<memfs::Memfs> vfs;
  fbl::RefPtr<memfs::VnodeDir> root;
  ASSERT_OK(memfs::Memfs::Create(dispatcher, "<tmp>", &vfs, &root));

  zx::vmo read_only_vmo;
  ASSERT_OK(zx::vmo::create(64, 0, &read_only_vmo));
  ASSERT_OK(read_only_vmo.write("hello, world!", 0, 13));
  ASSERT_OK(vfs->CreateFromVmo(root.get(), "greeting", read_only_vmo.get(), 0, 13));
  ASSERT_OK(vfs->ServeDirectory(std::move(root), std::move(directory_endpoints->server)));

  zx::status node_endpoints = fidl::CreateEndpoints<fio::Node>();
  ASSERT_OK(node_endpoints.status_value());
  auto open_result = fidl::WireCall(directory_endpoints->client)
                         ->Open(fio::wire::OpenFlags::kRightReadable, 0,
                                fidl::StringView("greeting"), std::move(node_endpoints->server));
  ASSERT_OK(open_result.status());
  fidl::ClientEnd<fio::File> file(node_endpoints->client.TakeChannel());

  {
    const fidl::WireResult get_result =
        fidl::WireCall(file)->GetBackingMemory(fio::wire::VmoFlags::kRead);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_ok(), "%s", zx_status_get_string(get_response.error_value()));
    const zx::vmo& vmo = get_response.value()->vmo;
    ASSERT_TRUE(vmo.is_valid());
    ASSERT_EQ(get_rights(vmo), kCommonExpectedRights);
    uint64_t size;
    ASSERT_OK(vmo.get_prop_content_size(&size));
    ASSERT_EQ(size, 13);
  }

  {
    const fidl::WireResult get_result = fidl::WireCall(file)->GetBackingMemory(
        fio::wire::VmoFlags::kRead | fio::wire::VmoFlags::kPrivateClone);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_ok(), "%s", zx_status_get_string(get_response.error_value()));
    const zx::vmo& vmo = get_response.value()->vmo;
    ASSERT_TRUE(vmo.is_valid());
    ASSERT_EQ(get_rights(vmo), kCommonExpectedRights | ZX_RIGHT_SET_PROPERTY);
    uint64_t size;
    ASSERT_OK(vmo.get_prop_content_size(&size));
    ASSERT_EQ(size, 13);
  }

  {
    const fidl::WireResult get_result = fidl::WireCall(file)->GetBackingMemory(
        fio::wire::VmoFlags::kRead | fio::wire::VmoFlags::kExecute);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_error());
    ASSERT_STATUS(get_response.error_value(), ZX_ERR_ACCESS_DENIED);
  }

  {
    const fidl::WireResult get_result = fidl::WireCall(file)->GetBackingMemory(
        fio::wire::VmoFlags::kRead | fio::wire::VmoFlags::kWrite);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_error());
    ASSERT_STATUS(get_response.error_value(), ZX_ERR_ACCESS_DENIED);
  }

  {
    auto describe_result = fidl::WireCall(file)->Describe();
    ASSERT_OK(describe_result.status());
    fio::wire::NodeInfo* info = &describe_result->info;
    ASSERT_TRUE(info->is_vmofile());
    ASSERT_EQ(info->vmofile().offset, 0u);
    ASSERT_EQ(info->vmofile().length, 13u);
    ASSERT_TRUE(info->vmofile().vmo.is_valid());
    ASSERT_EQ(get_rights(info->vmofile().vmo), kCommonExpectedRights);
  }

  {
    const fidl::WireResult seek_result =
        fidl::WireCall(file)->Seek(fio::wire::SeekOrigin::kStart, 7u);
    ASSERT_TRUE(seek_result.ok(), "%s", seek_result.status_string());
    const fitx::result response = seek_result.value();
    ASSERT_TRUE(response.is_ok(), "%s", zx_status_get_string(response.error_value()));
    ASSERT_EQ(response.value()->offset_from_start, 7u);
  }

  shutdown_vfs(std::move(vfs));
}

TEST(VmofileTests, test_vmofile_exec) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  async_dispatcher_t* dispatcher = loop.dispatcher();

  zx::status directory_endpoints = fidl::CreateEndpoints<fio::Directory>();
  ASSERT_OK(directory_endpoints.status_value());

  std::unique_ptr<memfs::Memfs> vfs;
  fbl::RefPtr<memfs::VnodeDir> root;
  ASSERT_OK(memfs::Memfs::Create(dispatcher, "<tmp>", &vfs, &root));

  zx::vmo read_exec_vmo;
  ASSERT_OK(zx::vmo::create(64, 0, &read_exec_vmo));
  ASSERT_OK(read_exec_vmo.write("hello, world!", 0, 13));

  zx::status client_end = service::Connect<fuchsia_kernel::VmexResource>();
  ASSERT_OK(client_end.status_value());
  fidl::WireResult result = fidl::WireCall(client_end.value())->Get();
  ASSERT_TRUE(result.ok(), "%s", result.FormatDescription().c_str());
  auto& response = result.value();

  ASSERT_OK(read_exec_vmo.replace_as_executable(std::move(response.resource), &read_exec_vmo));
  ASSERT_OK(vfs->CreateFromVmo(root.get(), "read_exec", read_exec_vmo.get(), 0, 13));
  ASSERT_OK(vfs->ServeDirectory(std::move(root), std::move(directory_endpoints->server)));

  zx::status node_endpoints = fidl::CreateEndpoints<fio::Node>();
  ASSERT_OK(node_endpoints.status_value());
  auto open_result =
      fidl::WireCall(directory_endpoints->client)
          ->Open(fio::wire::OpenFlags::kRightReadable | fio::wire::OpenFlags::kRightExecutable, 0,
                 fidl::StringView("read_exec"), std::move(node_endpoints->server));
  ASSERT_OK(open_result.status());
  fidl::ClientEnd<fio::File> file(node_endpoints->client.TakeChannel());

  {
    const fidl::WireResult get_result =
        fidl::WireCall(file)->GetBackingMemory(fio::wire::VmoFlags::kRead);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_ok(), "%s", zx_status_get_string(get_response.error_value()));
    const zx::vmo& vmo = get_response.value()->vmo;
    ASSERT_TRUE(vmo.is_valid());
    ASSERT_EQ(get_rights(vmo), kCommonExpectedRights);
    uint64_t size;
    ASSERT_OK(vmo.get_prop_content_size(&size));
    ASSERT_EQ(size, 13);
  }

  {
    // Providing a backing VMO with ZX_RIGHT_EXECUTE in CreateFromVmo above should cause
    // VMO_FLAG_EXEC to work.
    const fidl::WireResult get_result = fidl::WireCall(file)->GetBackingMemory(
        fio::wire::VmoFlags::kRead | fio::wire::VmoFlags::kExecute);
    ASSERT_TRUE(get_result.ok(), "%s", get_result.FormatDescription().c_str());
    const auto& get_response = get_result.value();
    ASSERT_TRUE(get_response.is_ok(), "%s", zx_status_get_string(get_response.error_value()));
    const zx::vmo& vmo = get_response.value()->vmo;
    ASSERT_TRUE(vmo.is_valid());
    ASSERT_EQ(get_rights(vmo), kCommonExpectedRights | ZX_RIGHT_EXECUTE);
    uint64_t size;
    ASSERT_OK(vmo.get_prop_content_size(&size));
    ASSERT_EQ(size, 13);
  }

  {
    // Describe should also return a VMO with ZX_RIGHT_EXECUTE.
    auto describe_result = fidl::WireCall(file)->Describe();
    ASSERT_OK(describe_result.status());
    fio::wire::NodeInfo* info = &describe_result->info;
    ASSERT_TRUE(info->is_vmofile());
    ASSERT_EQ(info->vmofile().offset, 0u);
    ASSERT_EQ(info->vmofile().length, 13u);
    ASSERT_TRUE(info->vmofile().vmo.is_valid());
    ASSERT_EQ(get_rights(info->vmofile().vmo), kCommonExpectedRights | ZX_RIGHT_EXECUTE);
  }

  shutdown_vfs(std::move(vfs));
}

}  // namespace
