#ifndef ENCLAVE_T_H__
#define ENCLAVE_T_H__

#include <stdint.h>
#include <wchar.h>
#include <stddef.h>
#include "sgx_edger8r.h" /* for sgx_ocall etc. */


#include <stdlib.h> /* for size_t */

#define SGX_CAST(type, item) ((type)(item))

#ifdef __cplusplus
extern "C" {
#endif

void ecall_sahe_add(void* a, void* b, void* c, size_t outlen, int isLeftFloat, int isRightFloat);
void ecall_sahe_mul(void* a, long int b, void* c, size_t outlen);
void ecall_sahe_sub(void* a, void* b, void* c, size_t outlen, int isLeftFloat, int isRightFloat);
void ecall_sahe_neg(void* a, void* c, size_t outlen);
void ecall_smhe_mul(void* a, void* b, void* c, size_t outlen, int isLeftFloat, int isRightFloat);
void ecall_smhe_mulp(void* a, long int b, void* c, size_t outlen);
void ecall_smhe_div(void* a, void* b, void* c, size_t outlen, int isLeftFloat, int isRightFloat);
void ecall_smhe_pow(void* a, long int b, void* c, size_t outlen);
void ecall_smhe_inv(void* a, void* c, size_t outlen);
void ecall_ore_compare(void* a, void* b, int* c);
void ecall_genMasterKey(const char* path);
void ecall_openMasterKey(const char* path, void* out, size_t outlen);
void ecall_encryptKeyWithEnclave(const char* key, size_t keySize, const char* path);
void ecall_init(void* pTaskQueue);
sgx_status_t sl_init_switchless(void* sl_data);
sgx_status_t sl_run_switchless_tworker(void);

sgx_status_t SGX_CDECL ocall_ereport(const char* str);
sgx_status_t SGX_CDECL ocall_usleep(size_t us);
sgx_status_t SGX_CDECL ocall_read_dek(const char* filename, char* buffer, size_t max_size, size_t* actual_size);
sgx_status_t SGX_CDECL u_sgxprotectedfs_exclusive_file_open(void** retval, const char* filename, uint8_t read_only, int64_t* file_size, int32_t* error_code);
sgx_status_t SGX_CDECL u_sgxprotectedfs_check_if_file_exists(uint8_t* retval, const char* filename);
sgx_status_t SGX_CDECL u_sgxprotectedfs_fread_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size);
sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_node(int32_t* retval, void* f, uint64_t node_number, uint8_t* buffer, uint32_t node_size);
sgx_status_t SGX_CDECL u_sgxprotectedfs_fclose(int32_t* retval, void* f);
sgx_status_t SGX_CDECL u_sgxprotectedfs_fflush(uint8_t* retval, void* f);
sgx_status_t SGX_CDECL u_sgxprotectedfs_remove(int32_t* retval, const char* filename);
sgx_status_t SGX_CDECL u_sgxprotectedfs_recovery_file_open(void** retval, const char* filename);
sgx_status_t SGX_CDECL u_sgxprotectedfs_fwrite_recovery_node(uint8_t* retval, void* f, uint8_t* data, uint32_t data_length);
sgx_status_t SGX_CDECL u_sgxprotectedfs_do_file_recovery(int32_t* retval, const char* filename, const char* recovery_filename, uint32_t node_size);
sgx_status_t SGX_CDECL sgx_oc_cpuidex(int cpuinfo[4], int leaf, int subleaf);
sgx_status_t SGX_CDECL sgx_thread_wait_untrusted_event_ocall(int* retval, const void* self);
sgx_status_t SGX_CDECL sgx_thread_set_untrusted_event_ocall(int* retval, const void* waiter);
sgx_status_t SGX_CDECL sgx_thread_setwait_untrusted_events_ocall(int* retval, const void* waiter, const void* self);
sgx_status_t SGX_CDECL sgx_thread_set_multiple_untrusted_events_ocall(int* retval, const void** waiters, size_t total);
sgx_status_t SGX_CDECL pthread_wait_timeout_ocall(int* retval, unsigned long long waiter, unsigned long long timeout);
sgx_status_t SGX_CDECL pthread_create_ocall(int* retval, unsigned long long self);
sgx_status_t SGX_CDECL pthread_wakeup_ocall(int* retval, unsigned long long waiter);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
