// 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/vfs/cpp/pseudo_file.h"

#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/limits.h>
#include <unistd.h>
#include <zircon/errors.h>
#include <zircon/processargs.h>

#include <algorithm>
#include <string>
#include <utility>
#include <vector>

#include "fuchsia/io/cpp/fidl.h"
#include "lib/gtest/real_loop_fixture.h"

namespace {

class FileWrapper {
 public:
  const std::string& buffer() { return buffer_; };

  vfs::PseudoFile* file() { return file_.get(); };

  static FileWrapper CreateReadWriteFile(std::string initial_str, size_t capacity,
                                         bool start_loop = true) {
    return FileWrapper(true, initial_str, capacity, start_loop);
  }

  static FileWrapper CreateReadOnlyFile(std::string initial_str, bool start_loop = true) {
    return FileWrapper(false, initial_str, initial_str.length(), start_loop);
  }

  async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }

  async::Loop& loop() { return loop_; }

 private:
  FileWrapper(bool write_allowed, std::string initial_str, size_t capacity, bool start_loop)
      : buffer_(std::move(initial_str)), loop_(&kAsyncLoopConfigNoAttachToThread) {
    auto readFn = [this](std::vector<uint8_t>* output, size_t max_file_size) {
      output->resize(buffer_.length());
      std::copy(buffer_.begin(), buffer_.end(), output->begin());
      return ZX_OK;
    };

    vfs::PseudoFile::WriteHandler writeFn;
    if (write_allowed) {
      writeFn = [this](std::vector<uint8_t> input) {
        std::string str(input.size(), 0);
        std::copy(input.begin(), input.begin() + input.size(), str.begin());
        buffer_ = std::move(str);
        return ZX_OK;
      };
    }

    file_ = std::make_unique<vfs::PseudoFile>(capacity, std::move(readFn), std::move(writeFn));
    if (start_loop) {
      loop_.StartThread("vfs test thread");
    }
  }

  std::unique_ptr<vfs::PseudoFile> file_;
  std::string buffer_;
  async::Loop loop_;
};

class PseudoFileTest : public gtest::RealLoopFixture {
 protected:
  void AssertOpen(vfs::internal::Node* node, async_dispatcher_t* dispatcher, uint32_t flags,
                  zx_status_t expected_status, bool test_on_open_event = true) {
    fuchsia::io::NodePtr node_ptr;
    if (test_on_open_event) {
      flags |= fuchsia::io::OPEN_FLAG_DESCRIBE;
    }
    EXPECT_EQ(expected_status, node->Serve(flags, node_ptr.NewRequest().TakeChannel(), dispatcher));

    if (test_on_open_event) {
      bool on_open_called = false;
      node_ptr.events().OnOpen = [&](zx_status_t status,
                                     std::unique_ptr<fuchsia::io::NodeInfo> info) {
        EXPECT_FALSE(on_open_called);  // should be called only once
        on_open_called = true;
        EXPECT_EQ(expected_status, status);
        if (expected_status == ZX_OK) {
          ASSERT_NE(info.get(), nullptr);
          EXPECT_TRUE(info->is_file());
        } else {
          EXPECT_EQ(info.get(), nullptr);
        }
      };

      RunLoopUntil([&]() { return on_open_called; });
    }
  }

  fuchsia::io::FileSyncPtr OpenReadWrite(vfs::internal::Node* node,
                                         async_dispatcher_t* dispatcher) {
    return OpenFile(node, fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
                    dispatcher);
  }

  fuchsia::io::FileSyncPtr OpenRead(vfs::internal::Node* node, async_dispatcher_t* dispatcher) {
    return OpenFile(node, fuchsia::io::OPEN_RIGHT_READABLE, dispatcher);
  }

  fuchsia::io::FileSyncPtr OpenFile(vfs::internal::Node* node, uint32_t flags,
                                    async_dispatcher_t* dispatcher) {
    fuchsia::io::FileSyncPtr ptr;
    node->Serve(flags, ptr.NewRequest().TakeChannel(), dispatcher);
    return ptr;
  }

  void AssertWriteAt(fuchsia::io::FileSyncPtr& file, const std::string& str, int offset,
                     zx_status_t expected_status = ZX_OK, int expected_actual = -1) {
    zx_status_t status;
    uint64_t actual;
    std::vector<uint8_t> buffer;
    buffer.resize(str.length());
    std::copy(str.begin(), str.end(), buffer.begin());
    file->WriteAt(buffer, offset, &status, &actual);
    ASSERT_EQ(expected_status, status);
    ASSERT_EQ(expected_actual == -1 ? str.length() : expected_actual, actual);
  }

  void AssertWrite(fuchsia::io::FileSyncPtr& file, const std::string& str,
                   zx_status_t expected_status = ZX_OK, int expected_actual = -1) {
    zx_status_t status;
    uint64_t actual;
    std::vector<uint8_t> buffer;
    buffer.resize(str.length());
    std::copy(str.begin(), str.end(), buffer.begin());
    file->Write(buffer, &status, &actual);
    ASSERT_EQ(expected_status, status);
    ASSERT_EQ(expected_actual == -1 ? str.length() : expected_actual, actual);
  }

  void AssertReadAt(fuchsia::io::FileSyncPtr& file, int offset, int count,
                    const std::string& expected_str, zx_status_t expected_status = ZX_OK) {
    zx_status_t status;
    std::vector<uint8_t> buffer;
    file->ReadAt(count, offset, &status, &buffer);
    ASSERT_EQ(expected_status, status);
    std::string str(buffer.size(), 0);
    std::copy(buffer.begin(), buffer.end(), str.begin());
    ASSERT_EQ(expected_str, str);
  }

  void AssertRead(fuchsia::io::FileSyncPtr& file, int count, const std::string& expected_str,
                  zx_status_t expected_status = ZX_OK) {
    zx_status_t status;
    std::vector<uint8_t> buffer;
    file->Read(count, &status, &buffer);
    ASSERT_EQ(expected_status, status);
    std::string str(buffer.size(), 0);
    std::copy(buffer.begin(), buffer.end(), str.begin());
    ASSERT_EQ(expected_str, str);
  }

  void AssertTruncate(fuchsia::io::FileSyncPtr& file, int count,
                      zx_status_t expected_status = ZX_OK) {
    zx_status_t status;
    file->Truncate(count, &status);
    ASSERT_EQ(expected_status, status);
  }

  void AssertSeek(fuchsia::io::FileSyncPtr& file, int64_t offest, fuchsia::io::SeekOrigin seek,
                  uint64_t expected_offset, zx_status_t expected_status = ZX_OK) {
    zx_status_t status;
    uint64_t new_offset;
    file->Seek(offest, seek, &status, &new_offset);
    ASSERT_EQ(expected_status, status);
    ASSERT_EQ(expected_offset, new_offset);
  }

  void CloseFile(fuchsia::io::FileSyncPtr& file, zx_status_t expected_status = ZX_OK) {
    zx_status_t status = 1;
    file->Close(&status);
    EXPECT_EQ(expected_status, status);
  }

  void AssertFileWrapperState(FileWrapper& file_wrapper, const std::string& expected_str) {
    RunLoopUntil([&]() { return file_wrapper.buffer() == expected_str; });
  }

  int OpenAsFD(vfs::internal::Node* node, async_dispatcher_t* dispatcher) {
    zx::channel local, remote;
    EXPECT_EQ(ZX_OK, zx::channel::create(0, &local, &remote));
    EXPECT_EQ(ZX_OK,
              node->Serve(fuchsia::io::OPEN_RIGHT_READABLE | fuchsia::io::OPEN_RIGHT_WRITABLE,
                          std::move(remote), dispatcher));
    int fd = -1;
    EXPECT_EQ(ZX_OK, fdio_fd_create(local.release(), &fd));
    return fd;
  }
};

TEST_F(PseudoFileTest, ServeOnInValidFlagsForReadWriteFile) {
  auto file_wrapper = FileWrapper::CreateReadWriteFile("test_str", 100, false);
  {
    SCOPED_TRACE("OPEN_FLAG_DIRECTORY");
    AssertOpen(file_wrapper.file(), dispatcher(), fuchsia::io::OPEN_FLAG_DIRECTORY, ZX_ERR_NOT_DIR);
  }
  uint32_t not_allowed_flags[] = {fuchsia::io::OPEN_RIGHT_ADMIN, fuchsia::io::OPEN_FLAG_CREATE,
                                  fuchsia::io::OPEN_FLAG_CREATE_IF_ABSENT,
                                  fuchsia::io::OPEN_FLAG_NO_REMOTE, fuchsia::io::OPEN_FLAG_APPEND};
  for (auto not_allowed_flag : not_allowed_flags) {
    SCOPED_TRACE(std::to_string(not_allowed_flag));
    AssertOpen(file_wrapper.file(), dispatcher(), not_allowed_flag, ZX_ERR_NOT_SUPPORTED);
  }
}

TEST_F(PseudoFileTest, ServeOnInValidFlagsForReadOnlyFile) {
  auto file_wrapper = FileWrapper::CreateReadOnlyFile("test_str");
  {
    SCOPED_TRACE("OPEN_FLAG_DIRECTORY");
    AssertOpen(file_wrapper.file(), dispatcher(), fuchsia::io::OPEN_FLAG_DIRECTORY, ZX_ERR_NOT_DIR);
  }
  uint32_t not_allowed_flags[] = {fuchsia::io::OPEN_RIGHT_ADMIN,
                                  fuchsia::io::OPEN_FLAG_CREATE,
                                  fuchsia::io::OPEN_FLAG_CREATE_IF_ABSENT,
                                  fuchsia::io::OPEN_FLAG_NO_REMOTE,
                                  fuchsia::io::OPEN_RIGHT_WRITABLE,
                                  fuchsia::io::OPEN_FLAG_TRUNCATE,
                                  fuchsia::io::OPEN_FLAG_APPEND};
  for (auto not_allowed_flag : not_allowed_flags) {
    SCOPED_TRACE(std::to_string(not_allowed_flag));
    AssertOpen(file_wrapper.file(), dispatcher(), not_allowed_flag, ZX_ERR_NOT_SUPPORTED);
  }
}

TEST_F(PseudoFileTest, ServeOnValidFlagsForReadWriteFile) {
  auto file_wrapper = FileWrapper::CreateReadWriteFile("test_str", 100, false);
  uint32_t allowed_flags[] = {fuchsia::io::OPEN_RIGHT_READABLE, fuchsia::io::OPEN_RIGHT_WRITABLE,
                              fuchsia::io::OPEN_FLAG_NODE_REFERENCE,
                              fuchsia::io::OPEN_FLAG_TRUNCATE,
                              fuchsia::io::OPEN_FLAG_NOT_DIRECTORY};
  for (auto allowed_flag : allowed_flags) {
    SCOPED_TRACE(std::to_string(allowed_flag));
    AssertOpen(file_wrapper.file(), dispatcher(), allowed_flag, ZX_OK);
  }
}

TEST_F(PseudoFileTest, ServeOnValidFlagsForReadOnlyFile) {
  auto file_wrapper = FileWrapper::CreateReadOnlyFile("test_str", false);
  uint32_t allowed_flags[] = {fuchsia::io::OPEN_RIGHT_READABLE,
                              fuchsia::io::OPEN_FLAG_NODE_REFERENCE};
  for (auto allowed_flag : allowed_flags) {
    SCOPED_TRACE(std::to_string(allowed_flag));
    AssertOpen(file_wrapper.file(), dispatcher(), allowed_flag, ZX_OK);
  }
}

TEST_F(PseudoFileTest, Simple) {
  auto file_wrapper = FileWrapper::CreateReadWriteFile("test_str", 100);

  int fd = OpenAsFD(file_wrapper.file(), file_wrapper.dispatcher());
  ASSERT_LE(0, fd);

  char buffer[1024];
  memset(buffer, 0, sizeof(buffer));
  ASSERT_EQ(5, pread(fd, buffer, 5, 0));
  EXPECT_STREQ("test_", buffer);

  ASSERT_EQ(4, write(fd, "abcd", 4));
  ASSERT_EQ(5, pread(fd, buffer, 5, 0));
  EXPECT_STREQ("abcd_", buffer);

  ASSERT_GE(0, close(fd));
  file_wrapper.loop().RunUntilIdle();

  AssertFileWrapperState(file_wrapper, "abcd_str");
}

TEST_F(PseudoFileTest, WriteAt) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWriteAt(file, "was", 5);

  const std::string updated_str = "this wasa test string";
  // confirm by reading
  AssertRead(file, str.length(), updated_str);

  // make sure file was not updated before conenction was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(file);

  AssertFileWrapperState(file_wrapper, updated_str);
}

TEST_F(PseudoFileTest, MultipleWriteAt) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWriteAt(file, "was", 5);

  AssertWriteAt(file, "tests", 10);

  const std::string updated_str = "this wasa testsstring";
  // confirm by reading
  AssertRead(file, str.length(), updated_str);

  // make sure file was not updated before conenction was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(file);

  AssertFileWrapperState(file_wrapper, updated_str);
}

TEST_F(PseudoFileTest, ReadAt) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertReadAt(file, 5, 10, str.substr(5, 10));

  // try one more
  AssertReadAt(file, 15, 5, str.substr(15, 5));
}

TEST_F(PseudoFileTest, Read) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertRead(file, 10, str.substr(0, 10));

  // offset should have moved
  AssertRead(file, 10, str.substr(10, 10));
}

TEST_F(PseudoFileTest, GetAttr) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  zx_status_t status;
  fuchsia::io::NodeAttributes attr;
  ASSERT_EQ(ZX_OK, file->GetAttr(&status, &attr));
  ASSERT_EQ(ZX_OK, status);
  ASSERT_NE(0u, attr.mode & fuchsia::io::MODE_TYPE_FILE);
  ASSERT_EQ(21u, attr.content_size);
}

TEST_F(PseudoFileTest, Write) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWrite(file, "It");

  // offset should have moved
  AssertWrite(file, " is");

  const std::string updated_str = "It isis a test string";

  AssertReadAt(file, 0, 100, updated_str);

  // make sure file was not updated before conenction was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(file);

  // make sure file was updated
  AssertFileWrapperState(file_wrapper, updated_str);
}

TEST_F(PseudoFileTest, Truncate) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertTruncate(file, 10);

  AssertRead(file, 100, str.substr(0, 10));

  // make sure file was not updated before conenction was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(file);

  // make sure file was updated
  AssertFileWrapperState(file_wrapper, str.substr(0, 10));
}

TEST_F(PseudoFileTest, SeekFromStart) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadOnlyFile(str);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, 5, fuchsia::io::SeekOrigin::START, 5);

  AssertRead(file, 100, str.substr(5));
}

TEST_F(PseudoFileTest, SeekFromCurent) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadOnlyFile(str);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, 5, fuchsia::io::SeekOrigin::START, 5);

  AssertSeek(file, 10, fuchsia::io::SeekOrigin::CURRENT, 15);

  AssertRead(file, 100, str.substr(15));
}

TEST_F(PseudoFileTest, SeekFromEnd) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadOnlyFile(str);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, -2, fuchsia::io::SeekOrigin::END, str.length() - 2);

  AssertRead(file, 100, str.substr(str.length() - 2));
}

TEST_F(PseudoFileTest, SeekFromEndWith0Offset) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadOnlyFile(str);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, 0, fuchsia::io::SeekOrigin::END, str.length());

  AssertRead(file, 100, "");
}

TEST_F(PseudoFileTest, SeekFailsIfOffsetMoreThanCapacity) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadOnlyFile(str);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, 1, fuchsia::io::SeekOrigin::END, 0, ZX_ERR_OUT_OF_RANGE);

  // make sure offset didnot change
  AssertRead(file, 100, str);
}

TEST_F(PseudoFileTest, WriteafterEndOfFile) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertSeek(file, 5, fuchsia::io::SeekOrigin::END, str.length() + 5);

  AssertWrite(file, "is");

  auto updated_str = str;
  updated_str.append(5, 0).append("is");

  AssertReadAt(file, 0, 100, updated_str);

  // make sure file was not updated before conenction was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(file);

  // make sure file was updated
  AssertFileWrapperState(file_wrapper, updated_str);
}

TEST_F(PseudoFileTest, WriteFailsForReadOnly) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWrite(file, "is", ZX_ERR_ACCESS_DENIED, 0);

  CloseFile(file);

  // make sure file was not updated
  AssertFileWrapperState(file_wrapper, str);
}

TEST_F(PseudoFileTest, WriteAtFailsForReadOnly) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWriteAt(file, "is", 0, ZX_ERR_ACCESS_DENIED, 0);

  CloseFile(file);

  // make sure file was not updated
  AssertFileWrapperState(file_wrapper, str);
}

TEST_F(PseudoFileTest, TruncateFailsForReadOnly) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenRead(file_wrapper.file(), file_wrapper.dispatcher());

  AssertTruncate(file, 10, ZX_ERR_ACCESS_DENIED);

  CloseFile(file);

  // make sure file was not updated
  AssertFileWrapperState(file_wrapper, str);
}

TEST_F(PseudoFileTest, ReadAtFailsForWriteOnly) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file =
      OpenFile(file_wrapper.file(), fuchsia::io::OPEN_RIGHT_WRITABLE, file_wrapper.dispatcher());

  AssertReadAt(file, 0, 10, "", ZX_ERR_ACCESS_DENIED);
}

TEST_F(PseudoFileTest, ReadFailsForWriteOnly) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file =
      OpenFile(file_wrapper.file(), fuchsia::io::OPEN_RIGHT_WRITABLE, file_wrapper.dispatcher());

  AssertRead(file, 10, "", ZX_ERR_ACCESS_DENIED);
}

TEST_F(PseudoFileTest, CapacityisSameAsFileContentSize) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, str.length());
  auto file =
      OpenFile(file_wrapper.file(), fuchsia::io::OPEN_RIGHT_READABLE, file_wrapper.dispatcher());

  AssertRead(file, str.length(), str);
}

TEST_F(PseudoFileTest, OpenFailsForOverFlowingFile) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, str.length() - 1);
  AssertOpen(file_wrapper.file(), file_wrapper.dispatcher(), fuchsia::io::OPEN_RIGHT_READABLE,
             ZX_ERR_FILE_BIG);
}

TEST_F(PseudoFileTest, CantReadNodeReferenceFile) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenFile(file_wrapper.file(), fuchsia::io::OPEN_FLAG_NODE_REFERENCE,
                       file_wrapper.dispatcher());
  // make sure node reference was opened
  zx_status_t status;
  fuchsia::io::NodeAttributes attr;
  ASSERT_EQ(ZX_OK, file->GetAttr(&status, &attr));
  ASSERT_EQ(ZX_OK, status);
  ASSERT_NE(0u, attr.mode | fuchsia::io::MODE_TYPE_FILE);

  std::vector<uint8_t> buffer;
  ASSERT_EQ(ZX_ERR_PEER_CLOSED, file->Read(100, &status, &buffer));
}

TEST_F(PseudoFileTest, CanCloneFileConnectionAndReadAndWrite) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  fuchsia::io::FileSyncPtr cloned_file;
  file->Clone(fuchsia::io::CLONE_FLAG_SAME_RIGHTS,
              fidl::InterfaceRequest<fuchsia::io::Node>(cloned_file.NewRequest().TakeChannel()));

  CloseFile(file);

  AssertWrite(cloned_file, "It");

  const std::string updated_str = "Itis is a test string";

  AssertReadAt(cloned_file, 0, 100, updated_str);

  // make sure file was not updated before connection was closed.
  ASSERT_EQ(file_wrapper.buffer(), str);

  CloseFile(cloned_file);

  // make sure file was updated
  AssertFileWrapperState(file_wrapper, updated_str);
}

TEST_F(PseudoFileTest, NodeReferenceIsClonedAsNodeReference) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapper::CreateReadWriteFile(str, 100);
  auto file = OpenFile(file_wrapper.file(), fuchsia::io::OPEN_FLAG_NODE_REFERENCE,
                       file_wrapper.dispatcher());

  fuchsia::io::FileSyncPtr cloned_file;
  file->Clone(fuchsia::io::CLONE_FLAG_SAME_RIGHTS,
              fidl::InterfaceRequest<fuchsia::io::Node>(cloned_file.NewRequest().TakeChannel()));
  CloseFile(file);

  // make sure node reference was opened
  zx_status_t status;
  fuchsia::io::NodeAttributes attr;
  ASSERT_EQ(ZX_OK, cloned_file->GetAttr(&status, &attr));
  ASSERT_EQ(ZX_OK, status);
  ASSERT_NE(0u, attr.mode | fuchsia::io::MODE_TYPE_FILE);

  std::vector<uint8_t> buffer;
  ASSERT_EQ(ZX_ERR_PEER_CLOSED, cloned_file->Read(100, &status, &buffer));
}

class FileWrapperWithFailingWriteFn {
 public:
  vfs::PseudoFile* file() { return file_.get(); };

  static FileWrapperWithFailingWriteFn Create(std::string initial_str, size_t capacity,
                                              zx_status_t write_error) {
    return FileWrapperWithFailingWriteFn(initial_str, capacity, write_error);
  }

  async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }

  async::Loop& loop() { return loop_; }

 private:
  FileWrapperWithFailingWriteFn(std::string initial_str, size_t capacity, zx_status_t write_error)
      : buffer_(std::move(initial_str)), loop_(&kAsyncLoopConfigNoAttachToThread) {
    auto readFn = [this](std::vector<uint8_t>* output, size_t max_file_size) {
      output->resize(buffer_.length());
      std::copy(buffer_.begin(), buffer_.end(), output->begin());
      return ZX_OK;
    };

    vfs::PseudoFile::WriteHandler writeFn;
    writeFn = [this, write_error](std::vector<uint8_t> input) {
      std::string str(input.size(), 0);
      std::copy(input.begin(), input.begin() + input.size(), str.begin());
      buffer_ = std::move(str);
      return write_error;
    };

    file_ = std::make_unique<vfs::PseudoFile>(capacity, std::move(readFn), std::move(writeFn));
    loop_.StartThread("vfs test thread");
  }

  std::unique_ptr<vfs::PseudoFile> file_;
  std::string buffer_;
  async::Loop loop_;
};

TEST_F(PseudoFileTest, CloseReturnsWriteError) {
  const std::string str = "this is a test string";
  auto file_wrapper = FileWrapperWithFailingWriteFn::Create(str, 100, ZX_ERR_IO);
  auto file = OpenReadWrite(file_wrapper.file(), file_wrapper.dispatcher());

  AssertWrite(file, "It");

  CloseFile(file, ZX_ERR_IO);
}

}  // namespace
