/*
 * Processes a market price response.
 */
RsslRet processMarketPriceResponse(RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslMsgKey* key = 0;
	RsslFieldList fList = RSSL_INIT_FIELD_LIST;
	RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY;
	RsslRet ret = 0;
	char tempData[1024];
	RsslBuffer tempBuffer;
	RsslBool isBatchRequest = RSSL_FALSE;
	
	tempBuffer.data = tempData;
	tempBuffer.length = 1024;

	switch(msg->msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			printf("Received RefreshMsg for stream %i\n", msg->refreshMsg.msgBase.streamId);

			if (msg->refreshMsg.flags & RSSL_RFMF_HAS_SEQ_NUM)
				printf("SEQ. NO.: %u\n", msg->refreshMsg.seqNum);

			/* process just like update */
		case RSSL_MC_UPDATE:
			/* decode market price response */
			
			/* get key */
			key = (RsslMsgKey *)rsslGetMsgKey(msg);

			/* print out item name from key if it has it */
			if (key)
			{
				printf("%.*s\n", key->name.length, key->name.data);
			}
			if (msg->msgBase.msgClass == RSSL_MC_UPDATE)
			{
				printf("Received UpdateMsg for stream %i\n", msg->updateMsg.msgBase.streamId);
				/* When displaying update information, we should also display the updateType information. */
				printf("UPDATE TYPE: %u\n", msg->updateMsg.updateType);	

				if (msg->updateMsg.flags & RSSL_UPMF_HAS_SEQ_NUM)
					printf("SEQ. NO.: %u\n", msg->updateMsg.seqNum);
			}
			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			if (msg->msgBase.msgClass == RSSL_MC_REFRESH)
			{
				rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
				printf("%.*s\n", tempBuffer.length, tempBuffer.data);
			}

			/* decode field list */
			if ((ret = rsslDecodeFieldList(dIter, &fList, 0)) == RSSL_RET_SUCCESS)
			{
				/* decode each field entry in list */
				while ((ret = rsslDecodeFieldEntry(dIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER)
				{
					if (ret == RSSL_RET_SUCCESS)
					{
						if ((ret = decodeFieldEntry(&fEntry, dIter)) != RSSL_RET_SUCCESS)
						{
							return ret;
						}
					}
					else
					{
						printf("rsslDecodeFieldEntry() failed with return code: %d\n", ret);
						return RSSL_RET_FAILURE;
					}
				}
			}
			else
			{
				printf("rsslDecodeFieldList() failed with return code: %d\n", ret);
				return RSSL_RET_FAILURE;
			}
			break;
		case RSSL_MC_STATUS:
			if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
    		{
				printf("Received StatusMsg for stream %i\n", msg->statusMsg.msgBase.streamId);
    			rsslStateToString(&tempBuffer, &msg->statusMsg.state);
				printf("	%.*s\n\n", tempBuffer.length, tempBuffer.data);
			}
			break;
		default:
			printf("\nReceived Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
   			break;
	}

	return RSSL_RET_SUCCESS;
}
/*
 * Publically visable market price response handler 
 *
 * Processes a market price response.  This consists of extracting the
 * key, printing out the item name contained in the key, decoding the
 * field list and field entry, and calling decodeFieldEntry() to decode
 * the field entry data.
 * msg - The partially decoded message
 * dIter - The decode iterator
 */
RsslRet processMarketPriceResponse(RsslChannel *chnl, RsslMsg* msg, RsslDecodeIterator* dIter)
{
	RsslMsgKey* key;
	RsslFieldList fList = RSSL_INIT_FIELD_LIST;
	RsslFieldEntry fEntry = RSSL_INIT_FIELD_ENTRY;
	RsslRet ret = 0;
	char tempData[1024];
	RsslBuffer tempBuffer;
	RsslBool isBatchRequest = RSSL_FALSE;
	RsslBool isPrivateStream = RSSL_FALSE;
	MarketPriceItemInfo *itemInfo = NULL;
	char postUserAddrString[16];

	tempBuffer.data = tempData;
	tempBuffer.length = sizeof(tempData);

	key = (RsslMsgKey *)rsslGetMsgKey(msg);

	// determine which item in the info list we received a response for
	if (msg->msgBase.streamId == MARKETPRICE_BATCH_STREAM_ID_START ||
		msg->msgBase.streamId == MARKETPRICE_BATCH_PRIVATE_STREAM_ID_START)
	{
		isBatchRequest = RSSL_TRUE;	// we dont have info list entries for a status response to a batch request
	}
	else if (msg->msgBase.streamId >= MARKETPRICE_PRIVATE_STREAM_ID_START)
	{
		isPrivateStream = RSSL_TRUE;
		itemInfo = &marketPricePSItemInfoList[msg->msgBase.streamId - MARKETPRICE_PRIVATE_STREAM_ID_START];
	}
	else if (msg->msgBase.streamId >= MARKETPRICE_STREAM_ID_START)
	{
		itemInfo = &marketPriceItemInfoList[msg->msgBase.streamId - MARKETPRICE_STREAM_ID_START];
	}

	switch(msg->msgBase.msgClass)
	{
		case RSSL_MC_REFRESH:
			if (!(msg->refreshMsg.flags & RSSL_RFMF_PRIVATE_STREAM)) /* non-private stream */
			{
				/* check if this response should be on private stream but is not */
				/* if this is the case, close the stream */
				if (isPrivateStream)
				{
					printf("\nReceived non-private response for stream %i that should be private - closing stream\n", msg->msgBase.streamId);
					/* close stream */
					if (closeMPItemStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
					/* remove private stream entry from list */
					removeMarketPriceItemEntry(chnl, itemInfo->streamId, RSSL_TRUE);
					return RSSL_RET_SUCCESS;
				}
			}

			/* update our item state list if its a refresh, then process just like update */
			itemInfo->itemState.dataState = msg->refreshMsg.state.dataState;
			itemInfo->itemState.streamState = msg->refreshMsg.state.streamState;

			/* refresh continued - process just like update */

		case RSSL_MC_UPDATE:

			/* print out item name from key if it has it */
			if (key && (key->flags & RSSL_MKF_HAS_NAME))
				printf("\n%.*s", key->name.length, key->name.data);
			else
				printf("\n%s", itemInfo->itemname);

			if (isPrivateStream) printf(" (PRIVATE STREAM)");
			printf("\n");

			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			if (msg->msgBase.msgClass == RSSL_MC_UPDATE)
			{
				/* When displaying update information, we should also display the updateType information. */
				printf("UPDATE TYPE: %u\n", msg->updateMsg.updateType);	

				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->updateMsg.flags & RSSL_UPMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->updateMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("Received UpdateMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->updateMsg.postUserInfo.postUserId, postUserAddrString);
				}
			}
			else if (msg->msgBase.msgClass == RSSL_MC_REFRESH)
			{
				rsslStateToString(&tempBuffer, &msg->refreshMsg.state);
				printf("%.*s\n", tempBuffer.length, tempBuffer.data);

				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->refreshMsg.flags & RSSL_RFMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->refreshMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("\nReceived RefreshMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->refreshMsg.postUserInfo.postUserId, postUserAddrString);
				}
			}


			/* decode market price response */
			/* decode field list */
			if ((ret = rsslDecodeFieldList(dIter, &fList, 0)) != RSSL_RET_SUCCESS)
			{
				printf("rsslDecodeFieldList() failed with return code: %d\n", ret);
				return RSSL_RET_FAILURE;
			}
			/* decode each field entry in list */
			while ((ret = rsslDecodeFieldEntry(dIter, &fEntry)) != RSSL_RET_END_OF_CONTAINER)
			{
				if (ret != RSSL_RET_SUCCESS)
				{
					printf("rsslDecodeFieldEntry() failed with return code: %d\n", ret);
					return RSSL_RET_FAILURE;
				}
				/* decode field entry info */
				if (decodeFieldEntry(&fEntry, dIter) != RSSL_RET_SUCCESS)
				{
					printf("\ndecodeFieldEntry() failed\n");
					return RSSL_RET_FAILURE;
				}
			}
			break;

		case RSSL_MC_STATUS:
			if (isBatchRequest)
				printf("\nReceived Batch StatusMsg for stream %i \n", msg->statusMsg.msgBase.streamId);
			else
				printf("\nReceived Item StatusMsg for stream %i \n", itemInfo->streamId);

			if (!(msg->statusMsg.flags & RSSL_STMF_PRIVATE_STREAM)) /* non-private stream */
			{
				/* check if this response should be on private stream but is not */
				/* if this is the case, close the stream */
				if (isPrivateStream)
				{
					printf("\nReceived non-private response for stream %i that should be private - closing stream\n", itemInfo->streamId);
					if (closeMPItemStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
					/* remove private stream entry from list */
					removeMarketPriceItemEntry(chnl, itemInfo->streamId, RSSL_TRUE);
					return RSSL_RET_SUCCESS;
				}
			}

			if (msg->statusMsg.flags & RSSL_STMF_HAS_STATE)
    		{
    			rsslStateToString(&tempBuffer, &msg->statusMsg.state);
				printf("	%.*s\n\n", tempBuffer.length, tempBuffer.data);

				if (itemInfo)
				{
					/* update our state table with the new state */
					itemInfo->itemState.dataState = msg->statusMsg.state.dataState;
					itemInfo->itemState.streamState = msg->statusMsg.state.streamState;
				}
				/* The Visible Publisher Identity (VPI) can be found within the RsslPostUserInfo. 
				 * This will provide both the publisher ID and publisher address. Consumer can obtain the information from the msg - The partially decoded message.
				 */
				if (msg->statusMsg.flags & RSSL_STMF_HAS_POST_USER_INFO)
				{
					rsslIPAddrUIntToString(msg->statusMsg.postUserInfo.postUserAddr, postUserAddrString);
					printf("Received StatusMsg for stream %i ", itemInfo->streamId);
					printf("from publisher with user ID: \"%u\" at user address: \"%s\"\n", msg->statusMsg.postUserInfo.postUserId, postUserAddrString);
				}

				/* redirect to private stream if indicated */
				if (msg->statusMsg.state.streamState == RSSL_STREAM_REDIRECTED &&
					(msg->statusMsg.flags & RSSL_STMF_PRIVATE_STREAM))
				{
    				if (redirectToMarketPricePrivateStream(chnl, itemInfo->streamId) != RSSL_RET_SUCCESS)
						return RSSL_RET_FAILURE;
				}
			}
			break;

		case RSSL_MC_ACK:
			printf("\nReceived AckMsg for stream %i \n", msg->msgBase.streamId);

			/* print out item name from key if it has it */
			/* if we sent an off stream post, we may not have created an itemInfo for it */
			if (key && (key->flags & RSSL_MKF_HAS_NAME))
				printf("\n%.*s", key->name.length, key->name.data);
			else if(itemInfo)	
				printf("\n%s", itemInfo->itemname);

			if (isPrivateStream) printf(" (PRIVATE STREAM)");
			printf("\n");

			printf("DOMAIN: %s\n", rsslDomainTypeToString(msg->msgBase.domainType));

			printf("\tackId=%u\n", msg->ackMsg.ackId);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_SEQ_NUM)
				printf("\tseqNum=%u\n", msg->ackMsg.seqNum);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_NAK_CODE)
				printf("\tnakCode=%u\n", msg->ackMsg.nakCode);
			if (msg->ackMsg.flags & RSSL_AKMF_HAS_TEXT)
				printf("\ttext=%.*s\n", msg->ackMsg.text.length, msg->ackMsg.text.data);

			break;

		default:
			printf("\nReceived Unhandled Item Msg Class: %d\n", msg->msgBase.msgClass);
   			break;
	}

	return RSSL_RET_SUCCESS;
}