#ifndef AIENGINE_H_
#define AIENGINE_H_

#define AIENGINE_VERSION "2.2.8"

#if (!(defined AIENGINE_CALL) || !(defined AIENGINE_IMPORT_OR_EXPORT))
#    if defined __WIN32__ || defined _WIN32 || defined _WIN64
#       define AIENGINE_CALL __stdcall
#       ifdef  AIENGINE_IMPLEMENTION
#           define AIENGINE_IMPORT_OR_EXPORT __declspec(dllexport)
#       else
#           define AIENGINE_IMPORT_OR_EXPORT __declspec(dllimport)
#       endif
#    else
#       define AIENGINE_CALL
#       define AIENGINE_IMPORT_OR_EXPORT __attribute ((visibility("default")))
#    endif
#endif

#ifdef __cplusplus
extern "C" {
#endif

enum {
    AIENGINE_MESSAGE_TYPE_JSON = 1,
    AIENGINE_MESSAGE_TYPE_BIN
};

#define AIENGINE_GET_VERSION       AIENGINE_OPT_GET_VERSION
#define AIENGINE_GET_MODULES       AIENGINE_OPT_GET_MODULES
#define AIENGINE_GET_TRAFFIC       AIENGINE_OPT_GET_TRAFFIC
#define AIENGINE_SET_WIFI_STATUS   AIENGINE_OPT_SET_WIFI_STATUS
#define AIENGINE_GET_PROVISION     AIENGINE_OPT_GET_PROVISION
#define AIENGINE_GET_SERIAL_NUMBER AIENGINE_OPT_GET_SERIAL_NUMBER
#define AIENGINE_SET_AILAS_ADDRESS AIENGINE_OPT_SET_AILAS_ADDRESS

enum {
    AIENGINE_OPT_INVALID  = 0,
    AIENGINE_OPT_GET_VERSION,
    AIENGINE_OPT_GET_MODULES,
    AIENGINE_OPT_GET_TRAFFIC,
    AIENGINE_OPT_SET_WIFI_STATUS,
    AIENGINE_OPT_GET_PROVISION,
    AIENGINE_OPT_GET_SERIAL_NUMBER,
    AIENGINE_OPT_SET_AILAS_ADDRESS,
    AIENGINE_OPT_MAX
};

struct aiengine;

typedef int (AIENGINE_CALL *aiengine_callback)(const void *usrdata, const char *id, int type, const void *message, int size);
AIENGINE_IMPORT_OR_EXPORT struct aiengine *AIENGINE_CALL aiengine_new(const char *cfg);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_delete(struct aiengine *engine);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_start(struct aiengine *engine, const char *param, char id[64], aiengine_callback callback, const void *usrdata);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_feed(struct aiengine *engine, const void *data, int size);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_stop(struct aiengine *engine);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_redo(struct aiengine *engine, char id[64], aiengine_callback callback, const void *usrdata);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_log(struct aiengine *engine, const char *log);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_device_id(char device_id[64]);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_cancel(struct aiengine *engine);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_opt(struct aiengine *engine, int opt, char *data, int size);
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_last_error_code();
AIENGINE_IMPORT_OR_EXPORT int AIENGINE_CALL aiengine_get_last_sub_error_code();
AIENGINE_IMPORT_OR_EXPORT const char *AIENGINE_CALL aiengine_get_last_error_text();

#ifdef __cplusplus
}
#endif
#endif
