/*
 * Copyright (C) Eugene 'Vindex' Stulin, 2025-2026
 *
 * Distributed under
 * the Boost Software License 1.0 or (at your option)
 * the GNU Lesser General Public License 3.0 or later.
 * This file is offered as-is, without any warranty.
 */

module oxfuse.fuse_conn_info;


/**
 * Connection information, passed to the initialize() method
 *
 * Some of the elements are read-write, these can be changed to
 * indicate the value requested by the filesystem.  The requested
 * value must usually be smaller than the indicated value.
 */
struct fuse_conn_info {
    /**
     * Major version of the protocol (read-only)
     */
    uint proto_major;

    /**
     * Minor version of the protocol (read-only)
     */
    uint proto_minor;

    /**
     * Maximum size of the write buffer
     */
    uint max_write;

    /**
     * Maximum size of read requests. A value of zero indicates no
     * limit. However, even if the filesystem does not specify a
     * limit, the maximum size of read requests will still be
     * limited by the kernel.
     *
     * NOTE: For the time being, the maximum size of read requests
     * must be set both here *and* passed to fuse_session_new()
     * using the ``-o max_read=<n>`` mount option. At some point
     * in the future, specifying the mount option will no longer
     * be necessary.
     */
    uint max_read;

    /**
     * Maximum readahead
     */
    uint max_readahead;

    /**
     * Capability flags that the kernel supports (read-only)
     */
    uint capable;

    /**
     * Capability flags that the filesystem wants to enable.
     *
     * libfuse attempts to initialize this field with
     * reasonable default values before calling the initialize() handler.
     */
    uint want;

    /**
     * Maximum number of pending "background" requests. A
     * background request is any type of request for which the
     * total number is not limited by other means. As of kernel
     * 4.8, only two types of requests fall into this category:
     *
     *   1. Read-ahead requests
     *   2. Asynchronous direct I/O requests
     *
     * Read-ahead requests are generated (if max_readahead is
     * non-zero) by the kernel to preemptively fill its caches
     * when it anticipates that userspace will soon read more
     * data.
     *
     * Asynchronous direct I/O requests are generated if
     * FUSE_CAP_ASYNC_DIO is enabled and userspace submits a large
     * direct I/O request. In this case the kernel will internally
     * split it up into multiple smaller requests and submit them
     * to the filesystem concurrently.
     *
     * Note that the following requests are *not* background
     * requests: writeback requests (limited by the kernel's
     * flusher algorithm), regular (i.e., synchronous and
     * buffered) userspace read/write requests (limited to one per
     * thread), asynchronous read requests (Linux's io_submit(2)
     * call actually blocks, so these are also limited to one per
     * thread).
     */
    uint max_background;

    /**
     * Kernel congestion threshold parameter. If the number of pending
     * background requests exceeds this number, the FUSE kernel module will
     * mark the filesystem as "congested". This instructs the kernel to
     * expect that queued requests will take some time to complete, and to
     * adjust its algorithms accordingly (e.g. by putting a waiting thread
     * to sleep instead of using a busy-loop).
     */
    uint congestion_threshold;

    /**
     * When FUSE_CAP_WRITEBACK_CACHE is enabled, the kernel is responsible
     * for updating mtime and ctime when write requests are received. The
     * updated values are passed to the filesystem with setattr() requests.
     * However, if the filesystem does not support the full resolution of
     * the kernel timestamps (nanoseconds), the mtime and ctime values used
     * by kernel and filesystem will differ (and result in an apparent
     * change of times after a cache flush).
     *
     * To prevent this problem, this variable can be used to inform the
     * kernel about the timestamp granularity supported by the file-system.
     * The value should be power of 10.  The default is 1, i.e. full
     * nano-second resolution. Filesystems supporting only second resolution
     * should set this to 1000000000.
     */
    uint time_gran;

    /**
     * For future use.
     */
    uint[22] reserved;
}

enum is64Bit = (void*).sizeof == 8 ? true : false;
static if (is64Bit) static assert(fuse_conn_info.sizeof == 128);


/// Simple wrapper for fuse_conn_info.
class ConnInfo {
    private fuse_conn_info* info;

    /// Returns pointer to struct fuse_conn_info from libfuse.
    fuse_conn_info* getRawPointer() {
        return info;
    }

    /// Constructor. Object of this class is created inside oxfuse.
    this(fuse_conn_info* connInfo) {
        this.info = connInfo;
    }
}

