#include <stdlib.h>

#include "cose.h"
#include "cose_int.h"

bool IsValidSignHandle(HCOSE_SIGN h)
{
	COSE_SignMessage * p = (COSE_SignMessage *)h;
	if (p == NULL) return false;
	return true;
}


HCOSE_SIGN COSE_Sign_Init(CBOR_CONTEXT_COMMA cose_errback * perror)
{
	COSE_SignMessage * pobj = (COSE_SignMessage *)COSE_CALLOC(1, sizeof(COSE_SignMessage), context);
	if (pobj == NULL) {
		if (perror != NULL) perror->err = COSE_ERR_OUT_OF_MEMORY;
		return NULL;
	}

	if (!_COSE_Init(&pobj->m_message, CBOR_CONTEXT_PARAM_COMMA perror)) {
	error_setup:
		COSE_Sign_Free((HCOSE_SIGN)pobj);
		return NULL;
	}

	if (!cn_cbor_mapput_int(pobj->m_message.m_cbor, COSE_Header_Type, cn_cbor_int_create(2, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL)) {
		if (perror != NULL) perror->err = COSE_ERR_OUT_OF_MEMORY;
		goto error_setup;
	}

	return (HCOSE_SIGN)pobj;
}

HCOSE_SIGN _COSE_Sign_Init_From_Object(cn_cbor * cbor, COSE_SignMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
{
	COSE_SignMessage * pobj = pIn;
	cn_cbor * pSigners = NULL;
	// cn_cbor * tmp;
	cose_errback error = { 0 };
	if (perr == NULL) perr = &error;

	if (pobj == NULL) pobj = (COSE_SignMessage *)COSE_CALLOC(1, sizeof(COSE_SignMessage), context);
	if (pobj == NULL) {
		perr->err = COSE_ERR_OUT_OF_MEMORY;
	errorReturn:
		if ((pIn == NULL) && (pobj != NULL)) COSE_FREE(pobj, context);
		return NULL;
	}

	if (!_COSE_Init_From_Object(&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	pSigners = (cn_cbor *)cn_cbor_mapget_int(cbor, COSE_Header_Recipients);
	if (pSigners != NULL) {
		CHECK_CONDITION(pSigners->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);

		pSigners = pSigners->first_child;
		while (pSigners != NULL) {
			COSE_SignerInfo * pInfo = _COSE_SignerInfo_Init_From_Object(pSigners, CBOR_CONTEXT_PARAM_COMMA perr);
			CHECK_CONDITION(pInfo != NULL, COSE_ERR_OUT_OF_MEMORY);

			pInfo->m_signerNext = pobj->m_signerFirst;
			pobj->m_signerFirst = pInfo;
			pSigners = pSigners->next;
		}
	}

	return(HCOSE_SIGN)pobj;
}

bool COSE_Sign_Free(HCOSE_SIGN h)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context context;
#endif

	if (!IsValidSignHandle(h)) return false;

#ifdef USE_CBOR_CONTEXT
	context = ((COSE_SignMessage *)h)->m_message.m_allocContext;
#endif

	_COSE_Sign_Release((COSE_SignMessage *)h);

	COSE_FREE((COSE_SignMessage *)h, &context);

	return true;
}

void _COSE_Sign_Release(COSE_SignMessage * p)
{
	// if (p->pbContent != NULL) COSE_FREE(p->pbContent, &p->m_message.m_allocContext);
	//	if (p->pbIV != NULL) COSE_FREE(p->pbIV, &p->m_message.m_allocContext);
	// if (p->pbKey != NULL) COSE_FREE(p->pbKey, &p->m_message.m_allocContext);

	_COSE_Release(&p->m_message);
}

bool COSE_Sign_SetContent(HCOSE_SIGN h, const byte * rgb, size_t cb, cose_errback * perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context;
#endif
	cn_cbor * p;
	COSE_SignMessage * pMessage = (COSE_SignMessage *)h;

	if (!IsValidSignHandle(h) || (rgb == NULL)) {
		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
		errorReturn:
		return false;
	}

#ifdef USE_CBOR_CONTEXT
	context = &((COSE_SignMessage *)h)->m_message.m_allocContext;
#endif

	p = cn_cbor_data_create(rgb, cb, CBOR_CONTEXT_PARAM_COMMA NULL);
	CHECK_CONDITION(p != NULL, CN_CBOR_ERR_OUT_OF_DATA);

	CHECK_CONDITION(cn_cbor_mapput_int(pMessage->m_message.m_cbor, COSE_Header_Ciphertext, p, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_OUT_OF_MEMORY);

	return true;
}

HCOSE_SIGNER COSE_Sign_add_signer(HCOSE_SIGN hSign, const cn_cbor * pkey, int algId, cose_errback * perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = NULL;
#endif
	COSE_SignMessage * pMessage = (COSE_SignMessage *)hSign;
	COSE_SignerInfo * pSigner = NULL;
	const cn_cbor * cbor;
	const cn_cbor * cbor2 = NULL;

	if (!IsValidSignHandle(hSign) || (pkey == NULL)) {
		if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
	errorReturn:
		if (cbor2 != NULL) CN_CBOR_FREE(cbor2, context);
		if (pSigner != NULL) _COSE_Signer_Free(pSigner);
		return NULL;
	}

	switch (algId) {
	case COSE_Algorithm_ECDSA_SHA_256:
		cbor = cn_cbor_mapget_int(pkey, COSE_Key_Type);
		CHECK_CONDITION(cbor != NULL, COSE_ERR_INVALID_PARAMETER);
		CHECK_CONDITION((cbor->type == CN_CBOR_UINT) && (cbor->v.uint == COSE_Key_Type_EC2), CN_CBOR_ERR_INVALID_PARAMETER);
		break;

	default:
		CHECK_CONDITION(false, COSE_ERR_INVALID_PARAMETER);
	}

#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	pSigner = (COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
	CHECK_CONDITION(pSigner != NULL, COSE_ERR_OUT_OF_MEMORY);

	if (!_COSE_Init(&pSigner->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;

	cbor = cn_cbor_mapget_int(pkey, COSE_Key_ID);
	if (cbor != NULL) {
		CHECK_CONDITION(cbor->type == CN_CBOR_BYTES, CN_CBOR_ERR_INVALID_PARAMETER);
		cbor2 = cn_cbor_data_create(cbor->v.str, cbor->length, CBOR_CONTEXT_PARAM_COMMA NULL);
		CHECK_CONDITION(cbor2 != NULL, COSE_ERR_CBOR);
		CHECK_CONDITION(cn_cbor_mapput_int(pSigner->m_message.m_unprotectMap, COSE_Parameter_KID, cbor2, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
		cbor2 = NULL;
	}

	pSigner->m_pkey = pkey;

	pSigner->m_signerNext = pMessage->m_signerFirst;
	pMessage->m_signerFirst = pSigner;

	cn_cbor * pSigners = (cn_cbor *)cn_cbor_mapget_int(pMessage->m_message.m_cbor, COSE_Header_Signers);
	if (pSigners == NULL) {
		pSigners = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
		CHECK_CONDITION(pSigners != NULL, COSE_ERR_OUT_OF_MEMORY);
		if (!cn_cbor_mapput_int(pMessage->m_message.m_cbor, COSE_Header_Signers, pSigners, CBOR_CONTEXT_PARAM_COMMA NULL)) {
			cn_cbor_free(pSigners, context);
			CHECK_CONDITION(false, COSE_ERR_CBOR);
		}
	}

	CHECK_CONDITION(cn_cbor_array_append(pSigners, pSigner->m_message.m_cbor, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);

	return (HCOSE_SIGNER)pSigner;
}

bool COSE_Sign_Sign(HCOSE_SIGN h, cose_errback * perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context * context = NULL;
#endif
	COSE_SignMessage * pMessage = (COSE_SignMessage *)h;
	COSE_SignerInfo * pSigner;
	const cn_cbor * pcborBody;
	const cn_cbor * pcborProtected;

	if (!IsValidSignHandle(h)) {
		CHECK_CONDITION(false, COSE_ERR_INVALID_PARAMETER);
	errorReturn:
		return false;
	}
#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	//  From this layer we use the protected fields and the body
	pcborBody = cn_cbor_mapget_int(pMessage->m_message.m_cbor, COSE_Header_Ciphertext);
	CHECK_CONDITION(pcborBody != NULL, COSE_ERR_INVALID_PARAMETER);

	pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
	if (pcborProtected == NULL) goto errorReturn;

	for (pSigner = pMessage->m_signerFirst; pSigner != NULL; pSigner = pSigner->m_signerNext) {
		if (!_COSE_Signer_sign(pSigner, pcborBody, pcborProtected, perr)) goto errorReturn;
	}

	return true;
}