/*
 * This file distributed under the terms of the GNU LGPLv2.
 * The module based on data from https://github.com/libfuse/libfuse
 */

/// The module contains `fuse_file_info` from libfuse ≥ 3.14.1.
module oxfuse.fuse_file_info.v3_14_1;


import std.bitmanip : bitfields;


/**
 * Information about an open file.
 *
 * File Handles are created by the open, opendir, and create methods and closed
 * by the release and releasedir methods. Multiple file handles may be
 * concurrently open for the same file. Generally, a client will create one
 * file handle per file descriptor, though in some cases multiple file
 * descriptors can share a single file handle.
 */
struct fuse_file_info {
    /// Open flags. Available in open() and release().
    int flags;

    mixin(bitfields!(
        /**
         * In case of a write() operation indicates if this was caused
         * by a delayed write from the page cache. If so, then the
         * context's pid, uid, and gid fields will not be valid, and
         * the `fh` value may not match the `fh` value that would
         * have been sent with the corresponding individual write
         * requests if write caching had been disabled.
         */
        uint, "writepage", 1,
        /// Can be filled in by open, to use direct I/O on this file.
        uint, "direct_io", 1,
        /**
         * Can be filled in by open(). It signals the kernel that any
         * currently cached file data (i.e., data that the filesystem
         * provided the last time the file was open) need not be invalidated.
         */
        uint, "keep_cache", 1,
        /**
         * Can be filled by open()/create(), to allow parallel direct writes
         * on this file.
         */
        uint, "parallel_direct_writes", 1, // !
        /**
         * Indicates a flush() operation. Set in flush() operation, also maybe
         * set in highlevel lock() operation and lowlevel release() operation.
         */
        uint, "flush", 1,
        /// Can be filled in by open, to indicate that the file isn't seekable.
        uint, "nonseekable", 1,
        /**
         * Indicates that flock locks for this file should be
         * released. If set, lock_owner shall contain a valid value.
         * May only be set in FileSystem.release().
         */
        uint, "flock_release", 1,
        /**
         * Can be filled in by opendir(). It signals the kernel
         * to enable caching of entries returned by readdir().
         */
        uint, "cache_readdir", 1,
        /**
         * Can be filled in by open(), to indicate that flush is not needed
         * on close.
         */
        uint, "noflush", 1,
        uint, "padding", 23
    ));
    uint padding2;
    uint padding3;

    /**
     * File handle id.
     * May be filled in by filesystem in create, open, and opendir().
     * Available in most other file operations on the same file handle.
     */
    ulong fh;

    /// Lock owner id. Available in locking operations and flush().
    ulong lock_owner;

    /**
     * Requested poll events. Available in poll.
     * Only set on kernels which support it.
     * If unsupported, this field is set to zero.
     */
    uint poll_events;
}

enum is64Bit = (void*).sizeof == 8 ? true : false;
static if (is64Bit) {
    static assert(fuse_file_info.fh.offsetof == 16);
    static assert(fuse_file_info.sizeof == 40);
}
