// 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_DIR_H_
#define LIB_VFS_CPP_PSEUDO_DIR_H_

#include <lib/vfs/cpp/internal/directory.h>

#include <map>
#include <mutex>

namespace vfs {

// A pseudo-directory is a directory-like object whose entries are constructed
// by a program at runtime.  The client can lookup, enumerate, and watch(not yet
// implemented) these directory entries but it cannot create, remove, or rename
// them.
//
// This class is thread-hostile, as are the |Nodes| it manages.
//
//  # 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: (a) the
// contents of the directory are configured prior to starting to service
// connections, (b) all modifications to the directory occur while the
// async_dispatcher_t for the background thread is stopped or suspended, and
// (c) async_dispatcher_t for the background thread is stopped or suspended
// prior to destroying the directory.
class PseudoDir : public vfs::internal::Directory {
 public:
  // Creates a directory which is initially empty.
  PseudoDir();

  // Destroys the directory and releases the nodes it contains.
  ~PseudoDir() override;

  // Adds a directory entry associating the given |name| with |vn|.
  // It is ok to add the same Node multiple times with different names.
  //
  // Returns |ZX_OK| on success.
  // Returns |ZX_ERR_ALREADY_EXISTS| if there is already a node with the given
  // name.
  zx_status_t AddSharedEntry(std::string name, std::shared_ptr<Node> vn);

  // Adds a directory entry associating the given |name| with |vn|.
  //
  // Returns |ZX_OK| on success.
  // Returns |ZX_ERR_ALREADY_EXISTS| if there is already a node with the given
  // name.
  zx_status_t AddEntry(std::string name, std::unique_ptr<Node> vn);

  // Removes a directory entry with the given |name|.
  //
  // Returns |ZX_OK| on success.
  // Returns |ZX_ERR_NOT_FOUND| if there is no node with the given name.
  zx_status_t RemoveEntry(const std::string& name);

  // Removes a directory entry with the given |name| and |node|.
  //
  // Returns |ZX_OK| on success.
  // Returns |ZX_ERR_NOT_FOUND| if there is no node with the given |name| and
  // matching |node| pointer.
  zx_status_t RemoveEntry(const std::string& name, Node* node);

  // Checks if directory is empty.
  // Be careful while using this function if using this Dir in multiple
  // threads.
  bool IsEmpty() const;

  // |Directory| implementation:
  zx_status_t Lookup(const std::string& name, vfs::internal::Node** out_node) const final;

  zx_status_t Readdir(uint64_t offset, void* data, uint64_t len, uint64_t* out_offset,
                      uint64_t* out_actual) override;

 private:
  class Entry {
   public:
    Entry(uint64_t id, std::string name);
    virtual ~Entry();

    uint64_t id() const { return id_; }
    const std::string& name() const { return name_; }
    virtual Node* node() const = 0;

   private:
    uint64_t const id_;
    std::string name_;
  };

  class SharedEntry : public Entry {
   public:
    SharedEntry(uint64_t id, std::string name, std::shared_ptr<Node> node);
    ~SharedEntry() override;

    Node* node() const override;

   private:
    std::shared_ptr<Node> node_;
  };

  class UniqueEntry : public Entry {
   public:
    UniqueEntry(uint64_t id, std::string name, std::unique_ptr<Node> node);
    ~UniqueEntry() override;

    Node* node() const override;

   private:
    std::unique_ptr<Node> node_;
  };

  zx_status_t AddEntry(std::unique_ptr<Entry> entry);

  static constexpr uint64_t kDotId = 1u;

  mutable std::mutex mutex_;

  std::atomic_uint64_t next_node_id_;

  // for enumeration
  std::map<uint64_t, std::unique_ptr<Entry>> entries_by_id_ __TA_GUARDED(mutex_);

  // for lookup
  std::map<std::string, Entry*> entries_by_name_ __TA_GUARDED(mutex_);
};

}  // namespace vfs
#endif  // LIB_VFS_CPP_PSEUDO_DIR_H_
