/****************************************************************************
**  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       **
****************************************************************************/

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

#ifndef SION_SION_GENERIC_INTERNAL_H
#define SION_SION_GENERIC_INTERNAL_H

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

#include "sion_buddy_common.h"
#include "sion_filedesc.h"
#include "sion_flags.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

/* internal interface routines, containing parallel functionality (e.g. meta data management) */
int _lsion_generic_paropen(int aid, const char *fname, const _sion_flags_store *flags_store, int64_t *chunksize,
  int32_t *fsblksize, void *gcommgroup, int grank, int gsize, int *filenumber, int *numfiles, const int *lrank, const int *lsize,
  FILE **fileptr, char **newfname);

/*!\brief Generic parallel open of one direct access file.
 *
 * @param  sid                   sion file handle
 * @param  fname                 filename to use
 * @param  flags_store           flags from already parsed file_mode (see also sion_internal.h)
 * @param  numFiles              Number of files to open
 * @param  filenumber            file number
 * @param  chunksize             chunksize on this task
 * @param  fsblksize             blocksize of filesystem (must be equal on all processors)
 * @param  rank                  rank of the current process
 * @param  ntasks                number of processes
 * @param  globalrank            any global unique id for this task, will be stored in sion file, usefull if comm is not MPI_COMM_WORLD
 *                               typical: globalrank= rank in MPI_COMM_WORLD
 * @param  flag                  sion options flag
 * @param  fileptr               filepointer for this task
 * @param  sion_gendata          structure, containing references to commgroups and callbacks
 * @param  buddy_info            data describing the buddy checkpointing
 *
 * @return  sion file handle
 *          -1 if error occured
 */
int _lsion_paropen_generic_one_file(int sid, char *fname, const _sion_flags_store *flags_store, int *numFiles, int *filenumber,
  int64_t *chunksize, int32_t *fsblksize, int rank, int ntasks, int *globalrank, int flag, FILE **fileptr,
  _sion_generic_gendata *sion_gendata, _sion_generic_buddy *buddy_info);

int _lsion_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 _lsion_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 _lsion_parreinit_generic(int sid, int64_t chunksize, int rank, int ntasks, _sion_generic_gendata *sion_gendata);

/* internal functions */
int _lsion_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 _lsion_generic_collect_mapping(_sion_filedesc *sion_filedesc, int *mapping_size, int32_t **mapping);

#endif

/// \endcond
