/*
 * Copyright (c) 2012-2014, 2025 LAAS/CNRS
 * All rights reserved.
 *
 * Redistribution and use  in source  and binary  forms,  with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *   1. Redistributions of  source  code must retain the  above copyright
 *      notice and this list of conditions.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice and  this list of  conditions in the  documentation and/or
 *      other materials provided with the distribution.
 *
 *					Anthony Mallet on Sun Mar 25 2012
 */

#ifndef H_GENOM3_C_CLIENT
#define H_GENOM3_C_CLIENT

#include <stddef.h>
#include <stdint.h>

#include <genom3/c/exception.h>
#include <genom3/c/context.h>

#define GENOM_CLIENT_DLSYM		"genom_client_info"

enum { genom_client_protocol = 20250116 };

typedef struct genom_client_s *genom_client;

typedef void (*genom_request_cb)(
  genom_client h, int rqstid, int done, genom_event report, void *output,
  const void *exdetail, void *cb_data);
typedef genom_event (*genom_request_sendfn)(
  genom_client h, const void *in,
  genom_request_cb sentcb, genom_request_cb donecb, void *cb_data,
  int *rqstid);

typedef genom_event (*genom_port_readfn)(genom_client h, void *data);
typedef genom_event (*genom_port_multiple_readfn)(genom_client h,
  const char *name, void *data);
typedef genom_event (*genom_port_multiple_writefn)(genom_client h,
  const char *name, const void *data);

typedef void *(*genom_port_datafn)(genom_client h);
typedef void *(*genom_port_multiple_datafn)(genom_client h, const char *name);

typedef genom_event (*genom_port_openfn)(genom_client h, const char *path,
  const char **name);
typedef genom_event (*genom_port_closefn)(genom_client h, const char *name);

typedef void (*genom_initfn)(void *data);
typedef void (*genom_finifn)(void *data);

typedef int (*genom_json_scanfn)(void *in, const char *json,
  char **endptr);
typedef int (*genom_json_printfn)(char **json, void *out);

struct genom_client_option {
  const char *option, *descr;
};

struct genom_service_info {
  const char *name;
  const char *input;
  const char *output;
  const char *meta;
  genom_initfn init_input, init_output;
  genom_finifn fini_input, fini_output;
  genom_json_scanfn json_scan;
  genom_json_printfn json_print;
  genom_request_sendfn send;
  size_t input_size;
  size_t output_size;
};

struct genom_port_info {
  const char *name;
  const char *datatype;
  const char *meta;
  genom_initfn init_data;
  genom_finifn fini_data;
  genom_json_printfn json_print;
  unsigned int simple;
  union {
    genom_port_datafn simple;
    genom_port_multiple_datafn multiple;
  } data;
  union {
    genom_port_readfn simple;
    genom_port_multiple_readfn multiple;
  } read;
  size_t data_size;
};

struct genom_pub_info {
  const char *name;
  const char *datatype;
  const char *meta;
  genom_initfn init_data;
  genom_finifn fini_data;
  genom_json_printfn json_print;
  genom_json_scanfn json_scan;
  genom_port_openfn open;
  genom_port_closefn close;
  genom_port_multiple_datafn data;
  genom_port_multiple_writefn write;
  size_t data_size;
};

struct genom_client_info {
  const uint32_t protocol;
  const char *name;
  const struct genom_client_option *options;

  genom_client (*init)(int argc, char *argv[],
                       genom_event *ex, const void **exdetail);
  void (*fini)(genom_client h);
  genom_context (*context)(genom_client h);
  const char *(*instance)(genom_client h);
  int (*eventfd)(genom_client h);
  const struct genom_service_info *(*service_info)(genom_client h, int rqstid);
  int (*done)(genom_client h, int rqstid);
  genom_event (*wait)(genom_client h, int rqstid);
  genom_event (*result)(genom_client h, int rqstid, genom_event *report,
                        void **output, void **exdetail);
  genom_event (*clean)(genom_client h, int rqstid);
  genom_event (*abort)(genom_client h, int rqstid);
  genom_event (*doevents)(genom_client h);
  char *(*json_error)(genom_client h, genom_event e, const void *detail);

  int nservices;
  const struct genom_service_info *services;

  int nports;
  const struct genom_port_info *ports;

  int npubs;
  const struct genom_pub_info *pubs;
};

#endif /* H_GENOM3_C_CLIENT */
