#pragma once
#ifndef DAVIX_POSIX_H
#define DAVIX_POSIX_H

#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <davix_types.h>



/**
  @file davix_posix.h
  @author Devresse Adrien

  @brief C POSIX like API of davix
 */

#ifndef __DAVIX_INSIDE__
#error "Only davix.h or davix.hpp should be included."
#endif

DAVIX_C_DECL_BEGIN

//
// POSIX like API
// Need Webdav support
//


/**
  @brief execute a POSIX stat query on a given WebDav URI

  POSIX-like operation,

  POSIX stat request on a given webdav endpoint
  @param sess : davix session handle
  @param params : request parameters, can be NULL
  @param url : url of the webdav file/directory
  @param st : stat structure
  @param err: Davix Error report
  @return 0 if success else a negative value
*/
int davix_posix_stat(davix_sess_t sess, davix_params_t params, const char* url, struct stat * st, davix_error_t* err);



/**
  @brief execute a POSIX mkdir query on a given WebDav URI

  POSIX-like operation,

  create a directory ( collection)  at the given url


  @param sess : davix session handle
  @param params : request parameters, can be NULL
  @param url : url of the folder to create
  @param right : remote file right
  @param err: Davix Error report
  @return 0 if success else a negative value
*/
int davix_posix_mkdir(davix_sess_t sess, davix_params_t _params, const char* url,  mode_t right, davix_error_t* err);



/**
  @brief execute a POSIX opendir query on a given WebDav URI

  POSIX-like operation

  open a directory for a listing operation

  @param sess : davix session handle
  @param params : request parameters, can be NULL
  @param url : url of the folder to list
  @param err: Davix Error report
  @return directory stream pointer or NULL if error
*/
DAVIX_DIR* davix_posix_opendir(davix_sess_t sess, davix_params_t params, const char* url, davix_error_t* err);



/**
  @brief execute a POSIX readdir query on a given WebDav URI

  POSIX-like operation

  returns a pointer to a dirent structure representing the next directory entry in the directory stream pointed to by dirp

  @param sess : davix session handle
  @param dirp : directory stream
  @param err: Davix Error report
  @return pointer to a dirent structure or NULL if error
*/
struct dirent* davix_posix_readdir(davix_sess_t sess, DAVIX_DIR* dirp, davix_error_t* err);


/**
  @brief execute a POSIX closedir query on a given WebDav URI

  POSIX-like operation

  close an open directory stream

  @param sess : davix session handle
  @param d : directory stream
  @param err: Davix Error report
  @return 0 if success else -1
*/
int davix_posix_closedir(davix_sess_t sess, DAVIX_DIR* dirp, davix_error_t* err);



/**
  @brief open  a file in a POSIX-like approach with HTTP(S)

  open a file for reading or/and writing

  @param sess : davix session handle
  @param params : request parameters, can be NULL
  @param url : url of the file to open
  @param flags : flags to use
  @param err: Davix Error report
  @return directory stream pointer or NULL if error
*/
DAVIX_FD* davix_posix_open(davix_sess_t sess, davix_params_t params, const char* url, int flags, davix_error_t* err);


/**
  @brief read a file in a POSIX-like approach with HTTP(S)
  behavior similar to the POSIX read function

  @param sess : davix session handle
  @param fd : davix file descriptor
  @param buffer : buffer to fill
  @param read_size : maximum number of bytes to read
  @param err: Davix Error report
  @return the size of data or a negative value if an error occured
 */
ssize_t davix_posix_read(davix_sess_t sess, DAVIX_FD* fd, void* buffer, size_t read_size, davix_error_t* err);


/**
  @brief write a file in a POSIX-like approach with HTTP(S)
  behavior similar to the POSIX write function

  @param sess : davix session handle
  @param fd : davix file descriptor
  @param buffer : buffer with the write content
  @param write_size : number of bytes to write
  @param err: Davix Error report
  @return the size of the written data or a negative value if an error occured
 */
ssize_t davix_posix_write(davix_sess_t sess, DAVIX_FD* fd, const void* buffer, size_t write_size, davix_error_t* err);


/**
  @brief move the cursor of a davix file with HTTP(S)
  behavior similar to the POSIX lseek function

  @param sess : davix session handle
  @param fd : davix file descriptor
  @param offset : offset in byte inside the file
  @param flags : lseek flags, similar to the lseek function
  @param err: Davix Error report
  @return the offset position or a negative value if an error occures
 */
off_t davix_posix_lseek(davix_sess_t sess, DAVIX_FD* fd, off_t offset, int flags, davix_error_t* err);

/**
  @brief close a davix file descriptor

  @param sess : davix session handle
  @param fd : davix file descriptor
  @param err: Davix Error report
  @return the offset position or a negative value if an error occures
 */
int davix_posix_close(davix_sess_t sess, DAVIX_FD* fd, davix_error_t* err);

DAVIX_C_DECL_END

#endif // DAVIX_POSIX_H
