#ifndef MIDAS_DRIVERS_EPICS_EPICS_CA_H
#define MIDAS_DRIVERS_EPICS_EPICS_CA_H

/*
 * Small, synchronous subset of the EPICS Channel Access client API.
 *
 * This interface intentionally supports only the operations needed by the
 * MIDAS EPICS frontend: scalar channel creation, get, put, and pend_io.
 *
 * Generated with OpenAI Codex 5.6 Sol-high, 29.08.2026, S. Ritt
 */

#ifdef __cplusplus
extern "C" {
#endif

struct ca_channel;
typedef struct ca_channel *chid;
typedef long chtype;
typedef unsigned short capri;
typedef double ca_real;

struct connection_handler_args {
   chid chid;
   long op;
};
typedef void caCh(struct connection_handler_args args);

#define DBR_STRING 0
#define DBR_SHORT  1
#define DBR_INT    DBR_SHORT
#define DBR_FLOAT  2
#define DBR_ENUM   3
#define DBR_CHAR   4
#define DBR_LONG   5
#define DBR_DOUBLE 6

#define CA_K_INFO    3
#define CA_K_ERROR   2
#define CA_K_SUCCESS 1
#define CA_K_WARNING 0
#define CA_K_SEVERE  4
#define CA_K_FATAL   (CA_K_ERROR | CA_K_SEVERE)

#define CA_M_SUCCESS 0x00000001
#define CA_DEFMSG(severity, number) (((number) << 3) | (severity))

#define ECA_NORMAL       CA_DEFMSG(CA_K_SUCCESS, 0)
#define ECA_SOCK         CA_DEFMSG(CA_K_ERROR, 4)
#define ECA_ALLOCMEM     CA_DEFMSG(CA_K_WARNING, 6)
#define ECA_TIMEOUT      CA_DEFMSG(CA_K_WARNING, 10)
#define ECA_NOSUPPORT    CA_DEFMSG(CA_K_WARNING, 11)
#define ECA_BADTYPE      CA_DEFMSG(CA_K_ERROR, 14)
#define ECA_INTERNAL     CA_DEFMSG(CA_K_FATAL, 17)
#define ECA_GETFAIL      CA_DEFMSG(CA_K_WARNING, 19)
#define ECA_PUTFAIL      CA_DEFMSG(CA_K_WARNING, 20)
#define ECA_BADCOUNT     CA_DEFMSG(CA_K_WARNING, 22)
#define ECA_BADSTR       CA_DEFMSG(CA_K_ERROR, 23)
#define ECA_DISCONN      CA_DEFMSG(CA_K_WARNING, 24)
#define ECA_NORDACCESS   CA_DEFMSG(CA_K_WARNING, 46)
#define ECA_NOWTACCESS   CA_DEFMSG(CA_K_WARNING, 47)
#define ECA_NOSEARCHADDR CA_DEFMSG(CA_K_WARNING, 49)
#define ECA_BADCHID      CA_DEFMSG(CA_K_ERROR, 51)
#define ECA_BADPRIORITY  CA_DEFMSG(CA_K_ERROR, 56)

#define CA_PRIORITY_DEFAULT 0

int ca_task_initialize(void);
int ca_task_exit(void);
int ca_create_channel(const char *name, caCh *connection_handler,
                      void *user, capri priority, chid *channel);
int ca_pend_io(ca_real timeout);
int ca_get(chtype type, chid channel, void *value);
int ca_put(chtype type, chid channel, const void *value);

const char *ca_message(long status);
void ca_signal_with_file_and_lineno(long status, const char *message,
                                   const char *file, int line);

#define SEVCHK(status, message)                                                \
   do {                                                                        \
      int ca_status_ = (status);                                               \
      if (!(ca_status_ & CA_M_SUCCESS))                                        \
         ca_signal_with_file_and_lineno(ca_status_, (message), __FILE__,       \
                                        __LINE__);                              \
   } while (0)

#ifdef __cplusplus
}
#endif

#endif
