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

  // Removes all directory entries.
  void RemoveAllEntries();

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