/****************************************************************************
**  SIONLIB     http://www.fz-juelich.de/jsc/sionlib                       **
*****************************************************************************
**  Copyright (c) 2008-2018                                                **
**  Forschungszentrum Juelich, Juelich Supercomputing Centre               **
**                                                                         **
**  See the file COPYRIGHT in the package base directory for details       **
****************************************************************************/

#ifndef SION_SION_SERIAL_H
#define SION_SION_SERIAL_H

/*!
 * \defgroup serial Serial API
 * @{
 * \brief Open (and close) SIONlib files from a single task
 * \see \ref overview
 */

#include <stdint.h>
#include <stdio.h>

#include "sion_enums.h"

#ifdef __cplusplus
extern "C" {
#endif

/* open/close */
/*!
 * @brief Open a sion file in serial mode.
 *
 * See \ref sion_open_description.
 *
 * @param[in]       fname         name of file, should be equal on all tasks
 * @param[in]       file_mode     like the type parameter of fopen. See \ref file_mode_description .
 * @param[in,out]   ntasks        number of tasks used to write this file
 * @param[in,out]   nfiles        number of physical files
 * @param[in,out]   chunksizes    chunksize for each task
 * @param[in,out]   fsblksize     blocksize of filesystem, must be equal on all processors
 * @param[in]       globalranks   rank numbers for which the file should be opened;
 *                                will be stored in sion file, useful if comm is not MPI_COMM_WORLD
 *                                typical: globalrank = rank in MPI_COMM_WORLD
 * @param[out]      fileptr       file pointer for this task
 *
 * @retval          sid           sion file handle or -1 if error occured
 */
int lsion_open(char *fname, const char *file_mode, int *ntasks, int *nfiles, int64_t **chunksizes, int32_t *fsblksize,
  int **globalranks, FILE **fileptr);

/*!
 * @brief Open a sion file for a specific rank
 *
 * See \ref sion_open_rank_description
 *
 * @param[in]           fname           name of file, should be equal on all tasks
 * @param[in,out]       file_mode       like the type parameter of fopen (currently recognized options: "rb", "wb")
 * @param[in,out]       chunksize       chunksize for this task
 * @param[in,out]       fsblksize       blocksize of filesystem, must be equal on all processors
 * @param[in]           rank            rank number for which the file should be open;
 *                                      will be stored in sion file, usefull if comm is not MPI_COMM_WORLD
 *                                      typical: globalrank= rank in MPI_COMM_WORLD
 * @param[out]          fileptr         file pointer for this task
 *
 * @retval              sid             sion file handle or -1 if error occured
 */
int lsion_open_rank(char *fname, const char *file_mode, int64_t *chunksize, int32_t *fsblksize, int *rank, FILE **fileptr);

/*!
 * @brief Close a sion file.
 *
 * See \ref sion_close_description .
 *
 *  @param[in]  sid     sion file handle
 *
 *  @return     SION_SUCCESS if close is ok
 */
int lsion_close(int sid);

typedef struct {
  int n_chunksizes; // default: 0
  int64_t *chunksizes; // default: fsblksize
  int32_t fsblksize; // default: auto-detect

  int n_multifile; // default: 1

  sion_keyval_mode keyval_mode; // default: SION_KEYVAL_MODE_NONE

  sion_lowlevel_api lowlevel_api; // default: SION_LOWLEVEL_API_C
} sion_options;

sion_options lsion_options_new();

void lsion_options_set_chunksizes(sion_options *options, int n, int64_t chunksizes[]);
void lsion_options_set_fsblksize(sion_options *options, int32_t fsblksize);

void lsion_options_set_multifile_number(sion_options *options, int multifile_number);

void lsion_options_set_keyval_mode(sion_options *options, sion_keyval_mode keyval_mode);

void lsion_options_set_lowlevel_api(sion_options *options, sion_lowlevel_api lowlevel_api);

int lsion_open_with_options(const char *fname, sion_open_mode mode, int n, const sion_options *options);
#ifdef __cplusplus
}
#endif

/// @}

#endif
