///
/// @file iowfile.h
/// @authors k. headley
/// @date 01 mar 2020

/// File IO wrapper API 
/// (use for cross-platform functions/apps)

/// @sa doxygen-examples.c for more examples of Doxygen markup


/////////////////////////
// Terms of use
/////////////////////////
/*
 Copyright Information
  
 Copyright 2002-2020 MBARI
 Monterey Bay Aquarium Research Institute, all rights reserved.
 
 Terms of Use
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 3 of the License, or
 (at your option) any later version. You can access the GPLv3 license at
 http://www.gnu.org/licenses/gpl-3.0.html
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details
 (http://www.gnu.org/licenses/gpl-3.0.html)
 
 MBARI provides the documentation and software code "as is", with no warranty,
 express or implied, as to the software, title, non-infringement of third party
 rights, merchantability, or fitness for any particular purpose, the accuracy of
 the code, or the performance or results which you may obtain from its use. You
 assume the entire risk associated with use of the code, and you agree to be
 responsible for the entire cost of repair or servicing of the program with
 which you are using the code.
 
 In no event shall MBARI be liable for any damages, whether general, special,
 incidental or consequential damages, arising out of your use of the software,
 including, but not limited to, the loss or corruption of your data or damages
 of any kind resulting from use of the software, any prohibited use, or your
 inability to use the software. You agree to defend, indemnify and hold harmless
 MBARI and its officers, directors, and employees against any claim, loss,
 liability or expense, including attorneys' fees, resulting from loss of or
 damage to property or the injury to or death of any person arising out of the
 use of the software.
 
 The MBARI software is provided without obligation on the part of the
 Monterey Bay Aquarium Research Institute to assist in its use, correction,
 modification, or enhancement.
 
 MBARI assumes no responsibility or liability for any third party and/or
 commercial software required for the database or applications. Licensee agrees
 to obtain and maintain valid licenses for any additional third party software
 required.
 */

// Always do this
#ifndef IOWFILE_H
#define IOWFILE_H

/////////////////////////
// Includes 
/////////////////////////
#include "cwg-shared.h"

#if  defined(__PIC24FJ256GA106__) || defined(__PIC24FJ256GA606__) || defined(__PIC24FJ1024GA606__)
#include "ff.h"
#elif defined(__unix__) || defined(__APPLE__) || defined(__CYGWIN__)
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/statvfs.h>
#elif defined(__WIN32) || defined(_WIN64)
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#endif


/////////////////////////
// Macros
/////////////////////////
#define IOF_SRCH_MAX_BYTES 64

/////////////////////////
// Type Definitions
//////////////////////// 

// IOW file IO error codes are mapped 1:1 to FatFS codes.
// i.e. IOW_* == FR_*
// For POSIX implementations, error numbers (errno.h) are
// mapped outside this range by adding 
// errno>0  : IOW_ERR_COUNT+errno 
// errno<=0 : errno
//
// iow_fstrerror() returns FR/IOW error names or strerror names as appropriate.
// Use macros IOW_POSIX2IOW_ERR and IOW_IOW2POSIX_ERR to translate
typedef enum{
    IOW_OK = 0,              // (0) Succeeded
    IOW_DISK_ERR,            // (1) A hard error occurred in the low level disk I/O layer
    IOW_INT_ERR,             // (2) Assertion failed
    IOW_NOT_READY,           // (3) The physical drive cannot work
    IOW_NO_FILE,             // (4) Could not find the file
    IOW_NO_PATH,             // (5) Could not find the path
    IOW_INVALID_NAME,        // (6) The path name format is invalid
    IOW_DENIED,              // (7) Access denied due to prohibited access or directory full
    IOW_EXIST,               // (8) Access denied due to prohibited access
    IOW_INVALID_OBJECT,      // (9) The file/directory object is invalid
    IOW_WRITE_PROTECTED,     // (10) The physical drive is write protected
    IOW_INVALID_DRIVE,       // (11) The logical drive number is invalid
    IOW_NOT_ENABLED,         // (12) The volume has no work area
    IOW_NO_FILESYSTEM,       // (13) There is no valid FAT volume
    IOW_MKFS_ABORTED,        // (14) The f_mkfs() aborted due to any parameter error
    IOW_TIMEOUT,             // (15) Could not get a grant to access the volume within defined period
    IOW_LOCKED,              // (16) The operation is rejected according to the file sharing policy
    IOW_NOT_ENOUGH_CORE,     // (17) LFN working buffer could not be allocated
    IOW_TOO_MANY_OPEN_FILES, // (18) Number of open files > _FS_SHARE
    IOW_INVALID_PARAMETER,   // (19) Given parameter is invalid
    IOW_UNKNOWN,             // (20) unknown error
    IOW_ERR_COUNT
}iow_error_t;
#define IOW_POSIX2IOW_ERR(n) (n>0 ? IOW_ERR_COUNT+n : n)
#define IOW_IOW2POSIX_ERR(n) (n>IOW_ERR_COUNT ? n-IOW_ERR_COUNT : n)


// file open/create mode flags map directly to FatFS flags (values are different)
// 
//Flag             Meaning
//FA_READ	       Specifies read access to the object. Data can be read from the file.
//FA_WRITE	       Specifies write access to the object. Data can be written to the file. 
//                 Combine with FA_READ for read-write access.
//FA_OPEN_EXISTING Opens the file. The function fails if the file is not existing. (Default)
//FA_CREATE_NEW	   Creates a new file. The function fails with FR_EXIST if the file is existing.
//FA_CREATE_ALWAYS Creates a new file. If the file is existing, it will be truncated and overwritten.
//FA_OPEN_ALWAYS   Opens the file if it is existing. If not, a new file will be created.
//FA_OPEN_APPEND   Same as FA_OPEN_ALWAYS except the read/write pointer is set end of the file.
//
//POSIX	FatFs
//"r"   FA_READ
//"r+"  FA_READ | FA_WRITE
//"w"   FA_CREATE_ALWAYS | FA_WRITE
//"w+"  FA_CREATE_ALWAYS | FA_WRITE | FA_READ
//"a"   FA_OPEN_APPEND | FA_WRITE
//"a+"  FA_OPEN_APPEND | FA_WRITE | FA_READ
//"wx"  FA_CREATE_NEW | FA_WRITE
//"w+x" FA_CREATE_NEW | FA_WRITE | FA_READ
 
typedef enum{
    IOW_READ         =0x1,
    IOW_WRITE        =0x2,
    IOW_CREATE_NEW   =0x4,
    IOW_CREATE_ALWAYS=0x8,
    IOW_OPEN_EXISTING=0x10,
    IOW_OPEN_ALWAYS  =0x20,
    IOW_OPEN_APPEND  =0x40,
}iow_mode_t;

/////////////////////////
// Exports
/////////////////////////

#ifdef __cplusplus
extern "C" {
#endif
    
extern iow_error_t iow_errno;

int iow_opendir(DIR_T **dp, const char *path);
int iow_readdir(DIR_T *dp, DIRENT_T **dest);
int iow_closedir(DIR_T *fp);

int iow_fopen(FILE_T **fp, const char *path, iow_mode_t flags);
int iow_fclose(FILE_T *fp);
int iow_ftruncate(FILE_T *fp);
int iow_frename(const char *old, const char *new);
int iow_unlink(const char *path);
size_t iow_fread(FILE_T *fp, void *dest, size_t len);
size_t iow_fwrite(FILE_T *fp, void *src, size_t len);
char *iow_fgets(FILE_T *fp, void *dest, size_t len);
int iow_fputs(FILE_T *fp, const char *src);
uint32_t iow_ftell(FILE_T *fp);
int iow_fseek(FILE_T *fp, uint32_t offset);
uint32_t iow_fsize(FILE_T *fp);
int iow_feof(FILE_T *fp);
int iow_ferror(FILE_T *fp);
void iow_clearerr(FILE_T *fp);
const char *iow_fstrerror(int err);
int iow_fsstat(const char *path, uint32_t *r_avail, FSYS_T **fsys);

void iow_delay_msec(uint32_t msec);
void iow_get_line(void *buf, size_t len);
int  iow_get_char(bool block);

#ifdef __cplusplus
}
#endif

#endif // THIS_FILE



