#include <assert.h>

#include "ta_logger.h"

#define CHECK_TEE_STATUS_SUCCESS_RETURN(msg) \
    if (TEE_SUCCESS != status) { \
        LOG_E("Failed to %s status = %x", msg, status);\
        return status; \
    }

#define CHECK_TEE_STATUS_SUCCESS_BREAK(msg) \
    if (TEE_SUCCESS != status) { \
        LOG_E("Failed to %s status = %x", msg, status);\
        break; \
    }

#define CHECK_TEE_STATUS_SUCCESS_CONTINUE(msg) \
    if (TEE_SUCCESS != status) { \
        LOG_I("Failed to %s status = %x", msg, status);\
        continue; \
    }

#define CHECK_MBEDTLS_RET_ZERO_RETURN(msg) \
    if (0 != ret) { \
        logMbedtlsError(ret, msg); \
        return ret; \
    } \

#define CHECK_MBEDTLS_RET_ZERO_BREAK(msg) \
    if (0 != ret) { \
        logMbedtlsError(ret, msg); \
        break; \
    }

#define CHECK_FUNCTION_ARGUMENT_RETURN(condition) \
    if (!(condition)) { \
        LOG_E("Unsatisfied condition "#condition""); \
        return TEE_ERROR_BAD_PARAMETERS; \
    }

#define CHECK_FUNCTION_ARGUMENT_RETURN_NULL(condition) \
    if (!(condition)) { \
        LOG_E("Unsatisfied condition "#condition""); \
        return NULL; \
    }

#define CHECK_FUNCTION_ARGUMENT_RETURN_ZERO(condition) \
    if (!(condition)) { \
        LOG_E("Unsatisfied condition "#condition""); \
        return 0; \
    }

#define CHECK_CONDITION_BREAK(condition) \
    if (!(condition)) { \
        LOG_E("Unsatisfied condition "#condition""); \
        status = TEE_ERROR_BAD_PARAMETERS; \
        break; \
    }

#define CHECK_CONDITION_RETURN(condition) \
    if (!(condition)) { \
        LOG_E("Unsatisfied condition "#condition""); \
        return TEE_ERROR_BAD_PARAMETERS; \
    }

#define CHECK_BUFFER_ALLOCATED_RETURN(pointer) \
    if (NULL == pointer) { \
        LOG_E("Failed to allocate memory."); \
        return TEE_ERROR_OUT_OF_MEMORY;\
    }

#define CHECK_BUFFER_ALLOCATED_BREAK(pointer) \
    if (NULL == pointer) { \
        LOG_E("Failed to allocate memory."); \
        status = TEE_ERROR_OUT_OF_MEMORY; \
        break; \
    }

#define CHECK_REQUEST_SIZE_RETURN() \
    if ((NULL == pRequest) || (sizeRequest != sizeof(*pRequest))) { \
        LOG_E("Wrong request data, actual(%u), expected(%u)", sizeRequest, (uint32_t)sizeof(*pRequest)); \
        return TEE_ERROR_BAD_PARAMETERS; \
    }

#define CHECK_RESPONSE_SIZE_RETURN() \
    if ((NULL == pResponse) || (sizeResponse != sizeof(*pResponse))) { \
        LOG_E("Wrong response data, actual(%u), expected(%u)", sizeResponse, (uint32_t)sizeof(*pResponse)); \
        return TEE_ERROR_BAD_PARAMETERS; \
    }

#define CHECK_BOOL_RET_VAL(val, ret)                \
do {                                                \
    if (!(val)) {                                   \
        LOG_E("%s UNEXPECTED!", #val);          \
        return ret;                                 \
    }                                               \
} while(0)

#define CHECK_FUNC_RET(func)                            \
do {                                                    \
    IFAA_Result ret = (func);                           \
    CHECK_BOOL_RET_VAL(IFAA_ERR_SUCCESS == ret, ret);   \
} while(0)

#ifdef IFBIO_RELEASE
#define TA_ASSERT(condition)
#else
#define TA_ASSERT(condition) \
    if (!(condition)) { \
        LOG_F("Unsatisfied condition "#condition""); \
        assert(condition); \
    }
#endif
