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

#pragma once

#include "trace.h"

#include <fdio/remoteio.h>

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

#include <zircon/assert.h>
#include <zircon/compiler.h>
#include <zircon/device/vfs.h>
#include <zircon/types.h>

#include <fdio/vfs.h>

#ifdef __Fuchsia__
#include <threads.h>
#include <fdio/io.h>
#endif

// VFS Helpers (vfs.c)
// clang-format off
#define VFS_FLAG_DEVICE          0x00000001
#define VFS_FLAG_MOUNT_READY     0x00000002
#define VFS_FLAG_DEVICE_DETACHED 0x00000004
#define VFS_FLAG_RESERVED_MASK   0x0000FFFF
// clang-format on

__BEGIN_CDECLS

typedef struct vfs_iostate vfs_iostate_t;

// Send an unmount signal on a handle to a filesystem and await a response.
zx_status_t vfs_unmount_handle(zx_handle_t h, zx_time_t deadline);

__END_CDECLS

#ifdef __cplusplus

#ifdef __Fuchsia__
#include <fs/dispatcher.h>
#include <zx/channel.h>
#include <zx/event.h>
#include <zx/vmo.h>
#include <fbl/mutex.h>
#endif  // __Fuchsia__

#include <fbl/intrusive_double_list.h>
#include <fbl/macros.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/unique_ptr.h>

namespace fs {

class Vnode;
class Vfs;

#ifdef __Fuchsia__

// MountChannel functions exactly the same as a channel, except that it
// intentionally destructs by sending a clean "shutdown" signal to the
// underlying filesystem. Up until the point that a remote handle is
// attached to a vnode, this wrapper guarantees not only that the
// underlying handle gets closed on error, but also that the sub-filesystem
// is released (which cleans up the underlying connection to the block
// device).
class MountChannel {
public:
    constexpr MountChannel() = default;
    explicit MountChannel(zx_handle_t handle) : channel_(handle) {}
    explicit MountChannel(zx::channel channel) : channel_(fbl::move(channel)) {}
    MountChannel(MountChannel&& other) : channel_(fbl::move(other.channel_)) {}

    zx::channel TakeChannel() { return fbl::move(channel_); }

    ~MountChannel() {
        if (channel_.is_valid()) {
            vfs_unmount_handle(channel_.release(), 0);
        }
    }

private:
    zx::channel channel_;
};

#endif // __Fuchsia__

// Helper class used to fill direntries during calls to Readdir.
class DirentFiller {
public:
    DISALLOW_COPY_ASSIGN_AND_MOVE(DirentFiller);

    DirentFiller(void* ptr, size_t len);

    // Attempts to add the name to the end of the dirent buffer
    // which is returned by readdir.
    zx_status_t Next(const char* name, size_t len, uint32_t type);

    zx_status_t BytesFilled() const {
        return static_cast<zx_status_t>(pos_);
    }

private:
    char* ptr_;
    size_t pos_;
    const size_t len_;
};

inline bool vfs_valid_name(const char* name, size_t len) {
    return (len <= NAME_MAX &&
            memchr(name, '/', len) == nullptr &&
            (len != 1 || strncmp(name, ".", 1)) &&
            (len != 2 || strncmp(name, "..", 2)));
}

// The VFS interface declares a default abtract Vnode class with
// common operations that may be overwritten.
//
// The ops are used for dispatch and the lifecycle of Vnodes are owned
// by RefPtrs.
//
// All names passed to the Vnode class are valid according to "vfs_valid_name".
//
// The lower half of flags (VFS_FLAG_RESERVED_MASK) is reserved
// for usage by fs::Vnode, but the upper half of flags may
// be used by subclasses of Vnode.
class Vnode : public fbl::RefCounted<Vnode> {
public:
#ifdef __Fuchsia__
    // Allocate iostate and register the transferred handle with a dispatcher.
    // Allows Vnode to act as server.
    virtual zx_status_t Serve(fs::Vfs* vfs, zx::channel channel, uint32_t flags);

    // Extract handle(s), type, and extra info from a vnode.
    // Returns the number of handles which should be returned on the requesting handle.
    virtual zx_status_t GetHandles(uint32_t flags, zx_handle_t* hnds,
                                   uint32_t* type, void* extra, uint32_t* esize) {
        *type = FDIO_PROTOCOL_REMOTE;
        return 0;
    }

    virtual zx_status_t WatchDir(zx::channel* out) { return ZX_ERR_NOT_SUPPORTED; }
    virtual zx_status_t WatchDirV2(Vfs* vfs, const vfs_watch_dir_t* cmd) {
        return ZX_ERR_NOT_SUPPORTED;
    }
#endif
    virtual void Notify(const char* name, size_t len, unsigned event) {}

    // Ensure that it is valid to open vn.
    virtual zx_status_t Open(uint32_t flags) = 0;

    // Closes vn. Typically, most Vnodes simply return "ZX_OK".
    virtual zx_status_t Close();

    // Read data from vn at offset.
    virtual ssize_t Read(void* data, size_t len, size_t off) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Write data to vn at offset.
    virtual ssize_t Write(const void* data, size_t len, size_t off) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Attempt to find child of vn, child returned on success.
    // Name is len bytes long, and does not include a null terminator.
    virtual zx_status_t Lookup(fbl::RefPtr<Vnode>* out, const char* name, size_t len) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Read attributes of vn.
    virtual zx_status_t Getattr(vnattr_t* a) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Set attributes of vn.
    virtual zx_status_t Setattr(vnattr_t* a) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Read directory entries of vn, error if not a directory.
    // FS-specific Cookie must be a buffer of vdircookie_t size or smaller.
    // Cookie must be zero'd before first call and will be used by.
    // the readdir implementation to maintain state across calls.
    // To "rewind" and start from the beginning, cookie may be zero'd.
    virtual zx_status_t Readdir(void* cookie, void* dirents, size_t len) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Create a new node under vn.
    // Name is len bytes long, and does not include a null terminator.
    // Mode specifies the type of entity to create.
    virtual zx_status_t Create(fbl::RefPtr<Vnode>* out, const char* name, size_t len, uint32_t mode) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Performs the given ioctl op on vn.
    // On success, returns the number of bytes received.
    virtual ssize_t Ioctl(uint32_t op, const void* in_buf, size_t in_len,
                          void* out_buf, size_t out_len) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Removes name from directory vn
    virtual zx_status_t Unlink(const char* name, size_t len, bool must_be_dir) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Change the size of vn
    virtual zx_status_t Truncate(size_t len) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Renames the path at oldname in olddir to the path at newname in newdir.
    // Called on the "olddir" vnode.
    // Unlinks any prior newname if it already exists.
    virtual zx_status_t Rename(fbl::RefPtr<Vnode> newdir,
                               const char* oldname, size_t oldlen,
                               const char* newname, size_t newlen,
                               bool src_must_be_dir, bool dst_must_be_dir) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Creates a hard link to the 'target' vnode with a provided name in vndir
    virtual zx_status_t Link(const char* name, size_t len, fbl::RefPtr<Vnode> target) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Acquire a vmo from a vnode.
    //
    // At the moment, mmap can only map files from read-only filesystems,
    // since (without paging) there is no mechanism to update either
    // 1) The file by writing to the mapping, or
    // 2) The mapping by writing to the underlying file.
    virtual zx_status_t Mmap(int flags, size_t len, size_t* off, zx_handle_t* out) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Syncs the vnode with its underlying storage
    virtual zx_status_t Sync() {
        return ZX_ERR_NOT_SUPPORTED;
    }

    virtual ~Vnode() {};

#ifdef __Fuchsia__
    // Attaches a handle to the vnode, if possible. Otherwise, returns an error.
    virtual zx_status_t AttachRemote(MountChannel h) { return ZX_ERR_NOT_SUPPORTED; }

    // The following methods are required to mount sub-filesystems. The logic
    // (and storage) necessary to implement these functions exists within the
    // "RemoteContainer" class, which may be composed inside Vnodes that wish
    // to act as mount points.

    // The vnode is acting as a mount point for a remote filesystem or device.
    virtual bool IsRemote() const { return false; }
    virtual zx::channel DetachRemote() { return zx::channel(); }
    virtual zx_handle_t WaitForRemote() { return ZX_HANDLE_INVALID; }
    virtual zx_handle_t GetRemote() const { return ZX_HANDLE_INVALID; }
    virtual void SetRemote(zx::channel remote) { ZX_DEBUG_ASSERT(false); }

    // The vnode is a device. Devices may opt to reveal themselves as directories
    // or endpoints, depending on context. For the purposes of our VFS layer,
    // during path traversal, devices are NOT treated as mount points, even though
    // they contain remote handles.
    bool IsDevice() const { return (flags_ & VFS_FLAG_DEVICE) && IsRemote(); }
    void DetachDevice() {
        ZX_DEBUG_ASSERT(flags_ & VFS_FLAG_DEVICE);
        flags_ |= VFS_FLAG_DEVICE_DETACHED;
    }
    bool IsDetachedDevice() const { return (flags_ & VFS_FLAG_DEVICE_DETACHED); }
#endif
protected:
    DISALLOW_COPY_ASSIGN_AND_MOVE(Vnode);
    Vnode() : flags_(0) {};

    uint32_t flags_;
};

#ifdef __Fuchsia__
// Non-intrusive node in linked list of vnodes acting as mount points
class MountNode final : public fbl::DoublyLinkedListable<fbl::unique_ptr<MountNode>> {
public:
    using ListType = fbl::DoublyLinkedList<fbl::unique_ptr<MountNode>>;
    constexpr MountNode() : vn_(nullptr) {}
    ~MountNode() { ZX_DEBUG_ASSERT(vn_ == nullptr); }

    void SetNode(fbl::RefPtr<Vnode> vn) {
        ZX_DEBUG_ASSERT(vn_ == nullptr);
        vn_ = vn;
    }

    zx::channel ReleaseRemote() {
        ZX_DEBUG_ASSERT(vn_ != nullptr);
        zx::channel h = vn_->DetachRemote();
        vn_ = nullptr;
        return h;
    }

    bool VnodeMatch(fbl::RefPtr<Vnode> vn) const {
        ZX_DEBUG_ASSERT(vn_ != nullptr);
        return vn == vn_;
    }

private:
    fbl::RefPtr<Vnode> vn_;
};

#endif

// The Vfs object contains global per-filesystem state, which
// may be valid across a collection of Vnodes.
//
// The Vfs object must outlive the Vnodes which it serves.
class Vfs {
public:
    Vfs();
    // Walk from vn --> out until either only one path segment remains or we
    // encounter a remote filesystem.
    zx_status_t Walk(fbl::RefPtr<Vnode> vn, fbl::RefPtr<Vnode>* out,
                     const char* path, const char** pathout) __TA_REQUIRES(vfs_lock_);
    // Traverse the path to the target vnode, and create / open it using
    // the underlying filesystem functions (lookup, create, open).
    zx_status_t Open(fbl::RefPtr<Vnode> vn, fbl::RefPtr<Vnode>* out,
                     const char* path, const char** pathout,
                     uint32_t flags, uint32_t mode) __TA_EXCLUDES(vfs_lock_);
    zx_status_t Unlink(fbl::RefPtr<Vnode> vn, const char* path, size_t len) __TA_EXCLUDES(vfs_lock_);
    ssize_t Ioctl(fbl::RefPtr<Vnode> vn, uint32_t op, const void* in_buf, size_t in_len,
                  void* out_buf, size_t out_len) __TA_EXCLUDES(vfs_lock_);

#ifdef __Fuchsia__
    void TokenDiscard(zx::event* ios_token) __TA_EXCLUDES(vfs_lock_);
    zx_status_t VnodeToToken(fbl::RefPtr<Vnode> vn, zx::event* ios_token,
                             zx::event* out) __TA_EXCLUDES(vfs_lock_);
    zx_status_t Link(zx::event token, fbl::RefPtr<Vnode> oldparent,
                     const char* oldname, const char* newname) __TA_EXCLUDES(vfs_lock_);
    zx_status_t Rename(zx::event token, fbl::RefPtr<Vnode> oldparent,
                       const char* oldname, const char* newname) __TA_EXCLUDES(vfs_lock_);

    Vfs(Dispatcher* dispatcher);

    void SetDispatcher(Dispatcher* dispatcher) { dispatcher_ = dispatcher; }

    // Dispatches to a Vnode over the specified handle (normal case)
    zx_status_t Serve(zx::channel channel, void* ios);

    // Serves a Vnode over the specified handle (used for creating new filesystems)
    zx_status_t ServeDirectory(fbl::RefPtr<fs::Vnode> vn, zx::channel channel);

    // Pins a handle to a remote filesystem onto a vnode, if possible.
    zx_status_t InstallRemote(fbl::RefPtr<Vnode> vn, MountChannel h) __TA_EXCLUDES(vfs_lock_);

    // Create and mount a directory with a provided name
    zx_status_t MountMkdir(fbl::RefPtr<Vnode> vn,
                           const mount_mkdir_config_t* config) __TA_EXCLUDES(vfs_lock_);

    // Unpin a handle to a remote filesystem from a vnode, if one exists.
    zx_status_t UninstallRemote(fbl::RefPtr<Vnode> vn, zx::channel* h) __TA_EXCLUDES(vfs_lock_);

    // Unpins all remote filesystems in the current filesystem, and waits for the
    // response of each one with the provided deadline.
    zx_status_t UninstallAll(zx_time_t deadline) __TA_EXCLUDES(vfs_lock_);

    // A lock which should be used to protect lookup and walk operations
    // TODO(smklein): Encapsulate the lock; make it private.
    mtx_t vfs_lock_{};
#endif

private:
    zx_status_t OpenLocked(fbl::RefPtr<Vnode> vn, fbl::RefPtr<Vnode>* out,
                           const char* path, const char** pathout,
                           uint32_t flags, uint32_t mode) __TA_REQUIRES(vfs_lock_);
#ifdef __Fuchsia__
    zx_status_t TokenToVnode(zx::event token, fbl::RefPtr<Vnode>* out) __TA_REQUIRES(vfs_lock_);
    zx_status_t InstallRemoteLocked(fbl::RefPtr<Vnode> vn, MountChannel h) __TA_REQUIRES(vfs_lock_);
    zx_status_t UninstallRemoteLocked(fbl::RefPtr<Vnode> vn,
                                      zx::channel* h) __TA_REQUIRES(vfs_lock_);
    // Waits for a remote handle on a Vnode to become ready to receive requests.
    // Returns |ZX_ERR_PEER_CLOSED| if the remote will never become available, since it is closed.
    // Returns |ZX_ERR_UNAVAILABLE| if there is no remote handle, or if the remote handle is not yet ready.
    // On success, returns the remote handle.
    zx_handle_t WaitForRemoteLocked(fbl::RefPtr<Vnode> vn) __TA_REQUIRES(vfs_lock_);
    // The mount list is a global static variable, but it only uses
    // constexpr constructors during initialization. As a consequence,
    // the .init_array section of the compiled vfs-mount object file is
    // empty; "remote_list" is a member of the bss section.
    MountNode::ListType remote_list_ __TA_GUARDED(vfs_lock_){};

    Dispatcher* dispatcher_{};
#endif  // ifdef __Fuchsia__
};

} // namespace fs

#endif // ifdef __cplusplus

__BEGIN_CDECLS

typedef struct vnattr vnattr_t;
typedef struct vdirent vdirent_t;

typedef struct vdircookie {
    uint64_t n;
    void* p;
} vdircookie_t;

// Handle incoming zxrio messages, dispatching them to vnode operations.
zx_status_t vfs_handler(zxrio_msg_t* msg, void* cookie);

__END_CDECLS
