// 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:
  // Deprecated, please use |ReadHandler|
  using DeprecatedReadHandler =
      fit::function<zx_status_t(std::vector<uint8_t>* output)>;

  // 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)>;

  [[deprecated("Please use other constructor")]] PseudoFile(
      DeprecatedReadHandler read_handler = DeprecatedReadHandler(),
      WriteHandler write_handler = WriteHandler(), size_t max_file_size = 1024);

  // 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 andread 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_
