// These definitions are here because they aren't required for the public
// interface, and they were quite confusing in cn-cbor.h

typedef struct {
	int m_flags;        //  Not sure what goes here yet
	int m_ownMsg : 1;	//  Do I own the pointer @ m_cbor?
	int m_ownUnprotectedMap : 1; //  Do I own the pointer @ m_unportectedMap?
	int m_msgType : 4;	//  What message type is this?
	cn_cbor * m_cbor;
	cn_cbor * m_protectedMap;
	cn_cbor * m_unprotectMap;
	cn_cbor * m_dontSendMap;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context m_allocContext;
#endif
} COSE;

struct _SignerInfo;
typedef struct _SignerInfo COSE_SignerInfo;

typedef struct {
	COSE m_message;	    // The message object
	COSE_SignerInfo * m_signerFirst;
} COSE_SignMessage;

typedef struct _SignerInfo {
	COSE m_message;
	byte * pbKey;
	size_t cbKey;
	const cn_cbor * m_pkey;
	COSE_SignerInfo * m_signerNext;
} COSE_SignerInfo;

struct _RecipientInfo;
typedef struct _RecipientInfo COSE_RecipientInfo;

typedef struct {
	COSE m_message;		// The message object
	COSE_RecipientInfo * m_recipientFirst;
	byte * pbContent;
	size_t cbContent;
	byte * pbKey;
	size_t cbKey;
} COSE_Encrypt;

typedef struct _RecipientInfo {
	COSE_Encrypt m_encrypt;
	COSE_RecipientInfo * m_recipientNext;
} COSE_RecipientInfo;

typedef struct {
	COSE m_message;			// The message object
	COSE_RecipientInfo * m_recipientFirst;
	byte * pbContent;
	size_t cbContent;
	byte * pbKey;
	size_t cbKey;
} COSE_MacMessage;

#ifdef USE_CBOR_CONTEXT
/**
* Allocate enough space for 1 `cn_cbor` structure.
*
* @param[in]  ctx  The allocation context, or NULL for calloc.
* @return          A pointer to a `cn_cbor` or NULL on failure
*/
#define CN_CALLOC(ctx) ((ctx) && (ctx)->calloc_func) ? \
    (ctx)->calloc_func(1, sizeof(cn_cbor), (ctx)->context) : \
    calloc(1, sizeof(cn_cbor));

/**
*  Allocate space required
*
* @param[in]	ctx  The allocation context, or NULL for normal calloc.
* @param[in]	count	Number of items to allocate
* @param[in]	size	Size of item to allocate
* @return				A pointer to the object needed
*/
#define COSE_CALLOC(count, size, ctx) ((((ctx)) && ((ctx)->calloc_func)) ? \
	((ctx)->calloc_func(count, size, (ctx)->context)) : \
	calloc(count, size))

/**
* Free a
* @param  free_func [description]
* @return           [description]
*/
#define COSE_FREE(ptr, ctx) (((ctx) && (ctx)->free_func) ? \
    ((ctx)->free_func((ptr), (ctx)->context)) : \
    free((ptr)))

#define CBOR_CONTEXT_PARAM , context
#define CBOR_CONTEXT_PARAM_COMMA context ,
//#define CN_CALLOC_CONTEXT() CN_CALLOC(context)
#define CN_CBOR_FREE(p, context) cn_cbor_free(p, context)

#else

#define CBOR_CONTEXT_PARAM
#define CN_CALLOC_CONTEXT() CN_CALLOC
#define COSE_CALLOC(ctx, count, size) calloc(count, size)
#define CN_CBOR_FREE(p, context) cn_cbor_free(p)

#define COSE_FREE(ptr, ctx) free(ptr)

#endif // USE_CBOR_CONTEXT

#ifndef UNUSED_PARAM
#define UNUSED_PARAM(p) ((void)&(p))
#endif

extern const cn_cbor * _COSE_encode_protected(COSE * pMessage, cose_errback * perr);


extern bool IsValidEncryptHandle(HCOSE_ENCRYPT h);
extern bool IsValidRecipientHandle(HCOSE_RECIPIENT h);

extern bool _COSE_Init(COSE * pcose, CBOR_CONTEXT_COMMA cose_errback * errp);
extern bool _COSE_Init_From_Object(COSE* pobj, cn_cbor * pcbor, CBOR_CONTEXT_COMMA cose_errback * perror);
extern void _COSE_Release(COSE * pcose);

extern const cn_cbor * _COSE_map_get_string(COSE * cose, const char * key, int flags, cose_errback * errp);
extern const cn_cbor * _COSE_map_get_int(COSE * cose, int key, int flags, cose_errback * errp);
extern bool _COSE_map_put(COSE * cose, int key, cn_cbor * value, int flags, cose_errback * errp);

extern HCOSE_ENCRYPT _COSE_Encrypt_Init_From_Object(cn_cbor *, COSE_Encrypt * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Encrypt_Release(COSE_Encrypt * p);
extern bool _COSE_Encrypt_decrypt(COSE_Encrypt * pcose, COSE_RecipientInfo * pRecip, int cbitKey, byte *pbKeyIn, cose_errback * perr);
extern void _COSE_Encrypt_SetContent(COSE_Encrypt * cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);

extern COSE_RecipientInfo * _COSE_Recipient_Init_From_Object(cn_cbor *, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Recipient_Free(COSE_RecipientInfo *);
extern bool _COSE_Recipient_decrypt(COSE_RecipientInfo * pRecip, int cbitKey, byte * pbKey, cose_errback * errp);
extern byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, size_t cbitKeySize);


//  Signed items
extern HCOSE_SIGN _COSE_Sign_Init_From_Object(cn_cbor *, COSE_SignMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Sign_Release(COSE_SignMessage * p);
extern bool _COSE_Signer_sign(COSE_SignMessage * pSigner, const cn_cbor * pcborBody, const cn_cbor * pcborProtected, cose_errback * perr);

//  Mac-ed items
extern HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *, COSE_MacMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern void _COSE_Mac_Release(COSE_MacMessage * p);


#define CHECK_CONDITION(condition, error) { if (!(condition)) { perr->err = error; goto errorReturn;}}
