/****************************************************************************
**  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
 * \brief Internal Functions(parallel)
 */

#ifndef SION_SION_GENERIC_BUDDY_H
#define SION_SION_GENERIC_BUDDY_H

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

#include "sion_buddy_common.h"
#include "sion_flags.h"
#include "sion_generic_apidesc.h"

/*!\brief Generic parallel open of a buddy checkpoint 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  fileptr               filepointer for this task
 * @param  sion_gendata          structure, containing references to commgroups and callbacks
 *
 * @return  sion file handle
 *          -1 if error occured
 */
int _lsion_paropen_generic_buddy(int sid, const char *fname, const _sion_flags_store *flags_store, int *numFiles, int *filenumber,
  int64_t *chunksize, int32_t *fsblksize, int rank, int ntasks, int *globalrank, FILE **fileptr,
  _sion_generic_gendata *sion_gendata);

/*!\brief Internal function to close parallel opened SION file and buddy files
 *
 * @param  sid  reference to file description struct (_sion_filedesc)
 * @param  rank  rank
 * @param  ntasks  number of tasks
 * @param  sion_gendata  generic data struct
 *
 * @return  SION_SUCCESS if successful
 */
int _lsion_parclose_generic_buddy(int sid, int rank, int ntasks, _sion_generic_gendata *sion_gendata);

/*!\brief Internal function to write data to buddy checkpoint file
 *
 * @param[in]  data   pointer to data to be written
 * @param[in]  size   size of a single item
 * @param[in]  nitems number of items to be written
 * @param[in]  sid    sion file id to be written to
 * @param  sion_gendata  generic data struct
 *
 * @return number of items written
 */
int64_t _lsion_coll_fwrite_buddy(const void *data, size_t size, size_t nitems, int sid, _sion_generic_gendata *sion_gendata);

/*!\brief Internal function to read data from buddy checkpoint file
 *
 * @param[out] data   pointer to data buffer
 * @param[in]  size   size of a single item
 * @param[in]  nitems number of items to be written
 * @param[in]  sid    sion file id to be written to
 *
 * @return number of items read
 */
int64_t _lsion_coll_fread_buddy(void *data, size_t size, size_t nitems, int sid);

int _lsion_buddy_map(_sion_generic_gendata *sion_gendata, int capability, int buddy_idx, _sion_generic_buddy_info *buddy_send,
  _sion_generic_buddy_info *buddy_coll);

int _lsion_buddy_bwsched(int groupnr, int numgroups, int pass);

/*!\brief collect mapping information on rank 0 of first file, mapping=NULL for all others
 *
 * @return 1 if successful
 */
int _lsion_generic_collect_mapping_buddy(
  _sion_generic_buddy *buddyptr, _sion_generic_gendata *sion_gendata, int *mapping_size, int32_t **mapping);

int _lsion_generic_buddy_get_and_distribute_info_from_file(_sion_generic_gendata *sion_gendata, char *fname, int root,
  int32_t *filenumber, int32_t *numfiles, int32_t *lrank, int32_t *lsize);

int _lsion_generic_buddy_get_and_distribute_info_from_one_file(_sion_generic_gendata *sion_gendata, char *fname, int root,
  int32_t *filenumber, int32_t *numfiles, int32_t *lrank, int32_t *lsize);

char *_lsion_buddy_role_to_str(unsigned int flag);

#endif

/// \endcond
