// 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.

#ifndef LIB_VFS_CPP_PSEUDO_FILE_H_
#define LIB_VFS_CPP_PSEUDO_FILE_H_

#include <lib/vfs/cpp/internal/connection.h>
#include <lib/vfs/cpp/internal/file.h>

namespace vfs {

// Buffered pseudo-file.
//
// This variant is optimized for incrementally reading and writing properties
// which are larger than can typically be read or written by the client in
// a single I/O transaction.
//
// In read mode, the pseudo-file invokes its read handler when the file is
// opened and retains the content in a buffer which the client incrementally
// reads from and can seek within.
//
// In write mode, the client incrementally writes into and seeks within the
// buffer which the pseudo-file delivers as a whole to the write handler when
// the file is closed(if there were any writes).  Truncation is also supported.
//
// This class is thread-hostile.
//
//  # Simple usage
//
// Instances of this class should be owned and managed on the same thread
// that services their connections.
//
// # Advanced usage
//
// You can use a background thread to service connections provided:
// async_dispatcher_t for the background thread is stopped or suspended
// prior to destroying the file.
class PseudoFile final : public vfs::internal::File {
 public:
  // Handler called to read from the pseudo-file.
  using ReadHandler = fit::function<zx_status_t(std::vector<uint8_t>* output, size_t max_bytes)>;

  // Handler called to write into the pseudo-file.
  using WriteHandler = fit::function<zx_status_t(std::vector<uint8_t> input)>;

  // Creates a buffered pseudo-file.
  //
  // |read_handler| cannot be null. If the |write_handler| is null, then the
  // pseudo-file is considered not writable. The |max_file_size|
  // determines the maximum number of bytes which can be written to and read from
  // the pseudo-file's input buffer when it it opened for writing/reading.
  PseudoFile(size_t max_file_size, ReadHandler read_handler = ReadHandler(),
             WriteHandler write_handler = WriteHandler());

  ~PseudoFile() override;

  // |Node| implementations:
  zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;

 protected:
  zx_status_t CreateConnection(uint32_t flags,
                               std::unique_ptr<vfs::internal::Connection>* connection) override;

  NodeKind::Type GetKind() const override;

 private:
  class Content final : public vfs::internal::Connection, public File {
   public:
    Content(PseudoFile* file, uint32_t flags, std::vector<uint8_t> content);
    ~Content() override;

    // |File| implementations:
    zx_status_t ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data) override;
    zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) override;
    zx_status_t Truncate(uint64_t length) override;

    uint64_t GetLength() override;

    size_t GetCapacity() override;

    // Connection implementation:
    zx_status_t BindInternal(zx::channel request, async_dispatcher_t* dispatcher) override;

    // |Node| implementations:
    std::unique_ptr<Connection> Close(Connection* connection) override;

    zx_status_t PreClose(Connection* connection) override;

    void Clone(uint32_t flags, uint32_t parent_flags, zx::channel request,
               async_dispatcher_t* dispatcher) override;

    zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const override;

   protected:
    void SendOnOpenEvent(zx_status_t status) override;

    NodeKind::Type GetKind() const override;

   private:
    zx_status_t TryFlushIfRequired();

    void SetInputLength(size_t length);

    PseudoFile* const file_;

    std::vector<uint8_t> buffer_;
    uint32_t flags_;

    // true if the file was written into
    bool dirty_ = false;
  };

  // |File| implementations:
  uint64_t GetLength() override;

  size_t GetCapacity() override;

  ReadHandler const read_handler_;
  WriteHandler const write_handler_;
  const size_t max_file_size_;
};

}  // namespace vfs

#endif  // LIB_VFS_CPP_PSEUDO_FILE_H_
