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

/*!
 * \cond sion_internal
 * \file
 *
 * \date Sep 2, 2008
 * \author gstu0808
 *
 */

#ifndef SION_SION_GENERIC_INTERNAL_H
#define SION_SION_GENERIC_INTERNAL_H

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

#include "sion_buddy_common.h"
#include "sion_enums.h"
#include "sion_filedesc.h"
#include "sion_flags.h"
#include "sion_generic.h"
#include "sion_generic_apidesc.h"

#define _SION_INTERNAL_FLAG_NORMAL 1
#define _SION_INTERNAL_FLAG_BUDDY_NORMAL 2
#define _SION_INTERNAL_FLAG_BUDDY_SEND 4
#define _SION_INTERNAL_FLAG_BUDDY_COLL 8
#define _SION_INTERNAL_FLAG_BUDDY_READ 16
#define _SION_INTERNAL_FLAG_UNKNOWN 32

struct sion_generic_options {
  int64_t chunksize; // default: fsblksize
  int32_t fsblksize; // default: auto-detect

  sion_keyval_mode keyval_mode; // default: SION_KEYVAL_MODE_NONE

  int32_t buddylevel; // default: 0, no buddy checkpointing

  int32_t collsize; // default: 0, do not use collective mode
  bool collective_merge; // default: false

  sion_lowlevel_api lowlevel_api; // default: SION_LOWLEVEL_API_C

  sion_endianness endianness; // default: SION_ENDIANNESS_HOST
};

#define SION_GENERIC_OPTIONS_INIT \
  (sion_generic_options) \
  { \
    .chunksize = -1, .fsblksize = -1, .keyval_mode = SION_KEYVAL_MODE_NONE, .buddylevel = 0, .collsize = 0, \
    .collective_merge = 0, .lowlevel_api = SION_LOWLEVEL_API_C, .endianness = SION_ENDIANNESS_HOST, \
  }

/* internal interface routines, containing parallel functionality (e.g. meta data management) */

int _sion_paropen_generic_one_file(int sid, const char *fname, sion_open_mode mode, int numfiles, int filenumber, int rank,
  int ntasks, int globalrank, int flag, _sion_generic_gendata *gendata, _sion_generic_buddy *buddy,
  const sion_generic_options *options);

int _sion_generic_paropen_mapped(int aid, char *fname, const _sion_flags_store *flags_store, int *numFiles, void *gcommgroup,
  int grank, int gsize, int *nlocaltasks, int **globalranks, int64_t **chunksizes, int **mapping_filenrs, int **mapping_lranks,
  int32_t *fsblksize, FILE **fileptr);

/*!\brief Internal function to close parallel opened SION file
 *
 * @param  sid  reference to file description struct (_sion_filedesc)
 * @param  rank  rank
 * @param  ntasks  number of tasks
 * @param  flag          flag describing the role if the process in buddy
 *                       checkpointing
 * @param  sion_gendata  generic data struct
 * @param  buddy_info    data describing the buddy checkpointing
 *
 * @return  SION_SUCCESS if successful
 */
int _sion_parclose_generic(
  int sid, int rank, int ntasks, int flag, _sion_generic_gendata *sion_gendata, _sion_generic_buddy *buddy_info);

/*!\brief change chunksize for an already opened SION file (write)
 *
 * @return 1 if successful
 */
int _sion_parreinit_generic(int sid, int64_t chunksize, int rank, int ntasks, _sion_generic_gendata *sion_gendata);

/* internal functions */
int _sion_generic_get_and_distribute_info_from_file(_sion_generic_gendata *sion_gendata, const char *fname);

/*!\brief collect mapping information on rank 0 of first file, mapping=NULL for all others
 *
 * @return 1 if successful
 */
int _sion_generic_collect_mapping(_sion_filedesc *sion_filedesc, int *mapping_size, int32_t **mapping);

#endif

/// \endcond
