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

#ifndef SION_SION_GENERIC_APIDESC_H
#define SION_SION_GENERIC_APIDESC_H

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

#define SION_GENERIC_API_LEVEL_NONE 70
#define SION_GENERIC_API_LEVEL_STD 71
#define SION_GENERIC_API_LEVEL_FULL 72

/* container describing API generated by the generic API */
struct _sion_generic_apidesc_struct {
  int aid;
  char *name;
  int level;

  /* STD callbacks */
  int (*create_lcg_cb)(void **, void *, int, int, int, int, int, int);
  int (*free_lcg_cb)(void *);

  int (*barrier_cb)(void *);
  int (*bcastr_cb)(void *, void *, int, int, int);
  int (*gatherr_cb)(void *, void *, void *, int, int, int);
  int (*gathervr_cb)(void *, void *, void *, int, int *, int, int);
  int (*scatterr_cb)(void *, void *, void *, int, int, int);
  int (*scattervr_cb)(void *, void *, void *, int, int *, int, int);
  char *(*get_multi_filename_cb)(const char *, int);

  /* callbacks for coalescing */
  int64_t (*gather_execute_cb)(const void *, int64_t, void *, int, int, int, int,
    int64_t process_cb(const void *, int64_t *, int), void *, bool spec_iterator_cb(void *, int64_t *));
  int64_t (*execute_scatter_cb)(void *, int64_t, void *, int, int, int, int, int64_t process_cb(void *, int64_t *, int), void *,
    bool spec_iterator_cb(void *, int64_t *));
  int (*get_capability_cb)(void *);
};
typedef struct _sion_generic_apidesc_struct _sion_generic_apidesc;

/*!\brief Allocates memory for internal sion api desc structure
 *
 * @retval      pointer to a new _sion_generic_apidesc structure
 */
_sion_generic_apidesc *_sion_generic_alloc_apidesc(void);

/*!\brief Initialize the sion api description
 *
 * @param  sion_apidesc  sion API description
 *
 * @retval  SION_SUCCESS if OK
 */
int _sion_generic_init_apidesc(_sion_generic_apidesc *sion_apidesc);

/*!\brief free apidesc structure
 *
 * @param  sion_apidesc  sion API description
 *
 * @retval  SION_SUCCESS if OK
 */
int _sion_generic_free_apidesc(_sion_generic_apidesc *sion_apidesc);

/* container describing additional data needed for each SION file opened with an API generated by the generic API */
struct _sion_generic_gendata_struct {
  _sion_generic_apidesc *apidesc;
  int aid;
  int grank;
  int gsize;
  int lrank;
  int lsize;
  int filenumber;
  int numfiles;
  void *comm_data_global;
  void *comm_data_local;
};
typedef struct _sion_generic_gendata_struct _sion_generic_gendata;

/*!\brief Allocates memory for internal sion api data structure needed for each SION file
 *
 * @retval      pointer to a new _sion_generic_gendata structure
 */
_sion_generic_gendata *_sion_generic_alloc_gendata(void);

/*!\brief Initialize the sion file description
 *
 * @param *sion_gendata     sion gendata description struct
 *
 * @retval      SION_SUCCESS if OK
 */
int _sion_generic_init_gendata(_sion_generic_gendata *sion_gendata);

/*!\brief Free sion gendata description
 *
 * @param *sion_gendata        sion gendata description struct
 *
 * @retval      SION_SUCCESS if OK
 */
int _sion_generic_free_gendata(_sion_generic_gendata *sion_gendata);

/*!\brief Update API level
 *
 * @param[inout]   sion_gendata   sion gendata description struct
 *
 * @retval      SION_SUCCESS if OK
 */
int _sion_generic_update_api_level(_sion_generic_apidesc *sion_gendata);

#endif

/// \endcond
