// 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_INTERNAL_NODE_H_
#define LIB_VFS_CPP_INTERNAL_NODE_H_

#include <fuchsia/io/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/binding.h>
#include <limits.h>

namespace vfs {
namespace internal {

bool IsValidName(const std::string& name);

class Connection;

// An object in a file system.
//
// Implements the |fuchsia.io.Node| interface. Incoming connections are owned by
// this object and will be destroyed when this object is destroyed.
//
// Subclass to implement a particular kind of file system object.
//
// See also:
//
//  * File, which is a subclass for file objects.
//  * Directory, which is a subclass for directory objects.
class Node {
 public:
  Node();
  virtual ~Node();

  Node(const Node&) = delete;
  Node& operator=(const Node&) = delete;

  // Notifies |Node| that it should remove and return
  // |connection| from its list as it is getting closed.
  virtual std::unique_ptr<Connection> Close(Connection* connection);

  // This function is called before |Close| is called and status is passed to
  // fuchsia::io::Node#Close| call.
  // Please note |Node| is closed even if this function returns error, so Node
  // should be ready a |Close| call.
  // Default implementation returns |ZX_OK|.
  virtual zx_status_t PreClose(Connection* connection);

  // Implementation of |fuchsia.io.Node/Describe|.
  //
  // Subclass must override this method to describe themselves accurately.
  virtual void Describe(fuchsia::io::NodeInfoDeprecated* out_info) = 0;

  // Implementation of |fuchsia.io.Node/Sync|.
  virtual zx_status_t Sync();

  // Implementation of |fuchsia.io.Node/GetAttr|.
  virtual zx_status_t GetAttr(fuchsia::io::NodeAttributes* out_attributes) const;

  // Implementation of |fuchsia.io.Node/SetAttr|.
  virtual zx_status_t SetAttr(fuchsia::io::NodeAttributeFlags flags,
                              const fuchsia::io::NodeAttributes& attributes);

  // Implementation of |fuchsia.io.Node/Clone|.
  virtual void Clone(fuchsia::io::OpenFlags flags, fuchsia::io::OpenFlags parent_flags,
                     zx::channel request, async_dispatcher_t* dispatcher);

  // Establishes a connection for |request| using the given |flags|.
  //
  // Waits for messages asynchronously on the |request| channel using
  // |dispatcher|. If |dispatcher| is |nullptr|, the implementation will call
  // |async_get_default_dispatcher| to obtain the default dispatcher for the
  // current thread.
  //
  // Calls |Connect| after validating flags and modes.
  zx_status_t Serve(fuchsia::io::OpenFlags flags, zx::channel request,
                    async_dispatcher_t* dispatcher = nullptr);

  // Find an entry in this directory with the given |name|.
  //
  // The entry is returned via |out_node|. The returned entry is owned by this
  // directory.
  //
  // Returns |ZX_ERR_NOT_FOUND| if no entry exists.
  // Default implementation in this class return |ZX_ERR_NOT_DIR| if
  // |IsDirectory| is false, else throws error with |ZX_ASSERT|.
  //
  // All directory types which are not remote should implement this method.
  virtual zx_status_t Lookup(const std::string& name, Node** out_node) const;

  // Return true if |Node| is a remote node.
  virtual bool IsRemote() const { return false; }

  // Return true if |Node| is a directory.
  virtual bool IsDirectory() const { return false; }

  // Implemented by subclasses that are remote directories. Forwards open requests to the remote
  // end.
  virtual void OpenRemote(fuchsia::io::OpenFlags flags, fuchsia::io::ModeType mode,
                          std::string_view path,
                          fidl::InterfaceRequest<fuchsia::io::Node> request) {
    ZX_PANIC("Unimplemented");
  }

 protected:
  // Returns total number of active connections
  uint64_t GetConnectionCount() const;

  // Called by |Serve| after validating flags and modes.
  // This should be implemented by sub classes which doesn't create a
  // connection class.
  //
  // Default implementation:
  // Uses |CreateConnection| to create a connection appropriate for the
  // concrete type of this object.
  virtual zx_status_t Connect(fuchsia::io::OpenFlags flags, zx::channel request,
                              async_dispatcher_t* dispatcher);

  // Sends OnOpen event on error status if |OPEN_FLAG_DESCRIBE| is set.
  static void SendOnOpenEventOnError(fuchsia::io::OpenFlags flags, zx::channel request,
                                     zx_status_t status);

  // Store given connection.
  void AddConnection(std::unique_ptr<Connection> connection);

  // Creates a |Connection| appropriate for the concrete type of this object.
  //
  // Subclasses must override this method to create an appropriate connection.
  // The returned connection should be in an "unbound" state.
  //
  // Typically called by |Serve|.
  virtual zx_status_t CreateConnection(fuchsia::io::OpenFlags flags,
                                       std::unique_ptr<Connection>* connection) = 0;

  // Allowed flags for use in |ValidateFlags|.
  //
  // See documentation of  |ValidateFlags| for exact details.
  virtual fuchsia::io::OpenFlags GetAllowedFlags() const = 0;

  // Prohibitive flags use in |ValidateFlags|.
  //
  // See documentation of  |ValidateFlags| for exact details.
  virtual fuchsia::io::OpenFlags GetProhibitiveFlags() const = 0;

 private:
  // Validate flags on |Serve|.
  //
  // If the caller specified an invalid combination of flags as per fuchsia.io,
  // returns |ZX_ERR_INVALID_ARGS|.
  //
  // Returns |ZX_ERR_NOT_DIR| if |OPEN_FLAG_DIRECTORY| is set and
  // |IsDirectory| returns false.
  //
  // Calls |GetProhibitiveFlags| flags and if one of the flag is in
  // prohibitive list, returns |ZX_ERR_INVALID_ARGS|.
  //
  // Calls |GetAllowedFlags|, appends |OPEN_FLAG_DESCRIBE|,
  // |OPEN_FLAG_NODE_REFERENCE|, |OPEN_FLAG_DIRECTORY| (only if
  // |IsDirectory| returns true) to those flags and returns
  // |ZX_ERR_NOT_SUPPORTED| if flags are not found in allowed list.
  //
  // Returns ZX_OK if none of the above cases are true.
  zx_status_t ValidateFlags(fuchsia::io::OpenFlags flags) const;

  // Filters out flags that are invalid when combined with
  // |OPEN_FLAG_NODE_REFERENCE|.
  // Allowed flags are |OPEN_FLAG_DIRECTORY| and |OPEN_FLAG_DESCRIBE|.
  fuchsia::io::OpenFlags FilterRefFlags(fuchsia::io::OpenFlags flags);

  // guards connection_
  mutable std::mutex mutex_;
  // The active connections associated with this object.
  std::vector<std::unique_ptr<Connection>> connections_ __TA_GUARDED(mutex_);
};

}  // namespace internal
}  // namespace vfs

#endif  // LIB_VFS_CPP_INTERNAL_NODE_H_
