/**
 * This file is part of the CernVM File System.
 */

#ifndef CVMFS_DUPLEX_FUSE_H_
#define CVMFS_DUPLEX_FUSE_H_

#ifdef CVMFS_LIBCVMFS
  // Unit tests
  #include <sys/types.h>
  #define FUSE_VERSION 29
  #define FUSE_ROOT_ID 1
  extern "C" {
    typedef unsigned long fuse_ino_t;  // NOLINT
    // Empty structs have different sizes in C and C++, hence the dummy int
    struct fuse_chan { int dummy; };
    struct fuse_lowlevel_ops { int dummy; };  // for loader.h
    enum fuse_expire_flags {
        FUSE_LL_EXPIRE_ONLY     = (1 << 0),
    };


    // Defined in t_fuse_evict.cc
    extern unsigned fuse_lowlevel_notify_inval_inode_cnt;
    extern unsigned fuse_lowlevel_notify_inval_entry_cnt;
    static int __attribute__((used)) fuse_lowlevel_notify_inval_inode(
      void *, unsigned /*fuse_ino_t*/, off_t, off_t)  // NOLINT (ulong from fuse)
    {
      fuse_lowlevel_notify_inval_inode_cnt++;
      return -1;
    }
    static int __attribute__((used)) fuse_lowlevel_notify_inval_entry(
      struct fuse_chan *, fuse_ino_t, const char *, size_t)  // NOLINT
    {
      fuse_lowlevel_notify_inval_entry_cnt++;
      return -1;
    }
  }
  #define CVMFS_USE_LIBFUSE 2
#else  // CVMFS_LIBCVMFS
  #ifndef CVMFS_USE_LIBFUSE
    #error "Build system error: CVMFS_USE_LIBFUSE unset"
  #endif

  #if CVMFS_USE_LIBFUSE == 2
    #define FUSE_USE_VERSION 26
    #include <fuse/fuse_lowlevel.h>
    #include <fuse/fuse_opt.h>
    #if(FUSE_VERSION < 28)
      #include <cstdlib>
      extern "C" {
        static int __attribute__((used)) fuse_lowlevel_notify_inval_entry(
          void *, unsigned long, const char *, size_t)  // NOLINT
        {
          abort();
        }
        static int __attribute__((used)) fuse_lowlevel_notify_inval_inode(
          void *, fuse_ino_t, off_t, off_t)  // NOLINT
        {
          abort();
        }
      }
    #endif  // FUSE_VERSION < 28
  #else
    // CVMFS_USE_LIBFUSE == 3
    #define FUSE_USE_VERSION 31
    #include <fuse3/fuse.h>
    #include <fuse3/fuse_lowlevel.h>
    #include <fuse3/fuse_opt.h>
  #endif
#endif

#endif  // CVMFS_DUPLEX_FUSE_H_
