/**@@@+++@@@@******************************************************************
**
** Microsoft Windows Media
** Copyright (C) Microsoft Corporation. All rights reserved.
**
***@@@---@@@@******************************************************************
*/


#include "tclib.h"
#include "tstutils.h"
#include "drmlicense.h"
#include "drmheaderparser.h"
#include "tstutils.h"
#include "drmcrt.h"
#include "tOEMIMP.h"
#include "DX_VOS_String.h"

DRM_CONST_STRING g_strContentHeader, g_strContentHeaderBackup, *g_pStrContentHeader;

/**********************************************************/

static DRM_RESULT DupDRMString(DRM_CONST_STRING* pTarget, DRM_CONST_STRING* pSource)
{
	DRM_RESULT dr = DRM_SUCCESS;
	pTarget->cchString = pSource->cchString;
	/*do allocation and memcopy only if the string has value*/
	if(pTarget->cchString)
	{
		ChkMem(pTarget->pwszString = (DRM_WCHAR*)DX_VOS_MemMalloc(sizeof(DRM_WCHAR) * pTarget->cchString));
		DX_VOS_FastMemCpy((void*)pTarget->pwszString, pSource->pwszString, sizeof(DRM_WCHAR) * pTarget->cchString);
	}
ErrorExit:
	return dr;
}

DRM_RESULT HD_PreTestCase(long lTCID, char *strTCName)
{
	g_strContentHeader.pwszString = g_strContentHeaderBackup.pwszString = NULL;
	g_pStrContentHeader = NULL;
	return DRM_SUCCESS;
}

DRM_RESULT HD_PostTestCase(long lTCID, char *strTCName)
{
	DX_VOS_MemFree((DRM_WCHAR*)g_strContentHeader.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)g_strContentHeaderBackup.pwszString);
	return DRM_SUCCESS;
}

IMPLEMENT_DEFAULT_WARPTEST


/* Load test file into g_strContentHeader, make a backup and set up g_pStrContentHeader
	argv[0]: xml file name, NULL, or EMPTY
*/
DRM_RESULT TestLoadHeader(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_BYTE *pbData = NULL;
	DRM_DWORD cbData;

	ChkArg(argc == 1);

	/* Clean up all global variables */
	ChkDR(HD_PostTestCase(0, NULL));
	ChkDR(HD_PreTestCase(0, NULL));

	if (argv[0]) {
		if (*argv[0]) {
			ChkArg(LoadTestFile(NULL, argv[0], &pbData, &cbData));
		}
		
		MakeDRMString(&g_strContentHeader, pbData? (DRM_CHAR*)pbData: "");

		ChkDR(DupDRMString(&g_strContentHeaderBackup, &g_strContentHeader));
		g_pStrContentHeader = &g_strContentHeader;
	}
ErrorExit:
	DX_VOS_MemFree(pbData);
	return dr;
}

/*	Test API DRM_HDR_Verify
	argv[0]: public key: validPubkey, wrongPubkey, InvalidPubkey, NULL
	argv[1]: crypto option: validCrypto, NULL
	argv[2]: return pointer option: NORMAL, NULL
	argv[3]: optional: expected returned value: 0, 1
*/
DRM_RESULT TestContentHeaderVerify(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_LONG lResult;

	/* Need to free these */
	DRM_CONST_STRING strPubKey, strPubKeyBackup;
	DRM_CRYPTO_CONTEXT *pCryptoContext = NULL;

	strPubKey.pwszString = strPubKeyBackup.pwszString = NULL;

	ChkArg(argc == 3 || (argc == 4 && argv[2]));

	/* set the public key */
	if (argv[0]) {
		MakeDRMString(&strPubKey, argv[0]);
		ChkDR(DupDRMString(&strPubKeyBackup, &strPubKey));
	}

	/* init crypto context */
	if (argv[1]) {
		ChkMem(pCryptoContext = (DRM_CRYPTO_CONTEXT*)DX_VOS_MemMalloc(sizeof(DRM_CRYPTO_CONTEXT)));
		DX_VOS_MemSet(pCryptoContext, 0, sizeof(DRM_CRYPTO_CONTEXT));
	}

	ChkDR(DRM_HDR_Verify(
		g_pStrContentHeader,
		argv[0]? &strPubKey: NULL,
		pCryptoContext,
		argv[2]? &lResult: NULL));

	/* Verify the content header is intact */
	if (g_pStrContentHeader && DRM_wcsncmp(g_strContentHeader.pwszString, g_strContentHeaderBackup.pwszString, g_strContentHeaderBackup.cchString))
		ChkDR(DRM_E_FAIL);

	/* Verify the public key is intact */
	if (argv[0] && DRM_wcsncmp(strPubKey.pwszString, strPubKeyBackup.pwszString, strPubKeyBackup.cchString))
		ChkDR(DRM_E_FAIL);

	if (argc > 3) { /* verify the result value */
		if (lResult != OEM_atol(argv[3]))
			dr = DRM_S_FALSE;
	}
ErrorExit:
	DX_VOS_MemFree((DRM_WCHAR*)strPubKey.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)strPubKeyBackup.pwszString);
	DX_VOS_MemFree(pCryptoContext);
	return dr;
}

/*	Test API DRM_HDR_GetAttribute
	argv[0]: attribute name: EMPTY, NULL or an actual attribute name
	argv[1]: attribute index: int, valid range is 1 - 5
	argv[2]: pointer to return data option: NORMAL, NULL
	argv[3]: optional: expected returned attribute data
*/
DRM_RESULT TestContentHeaderGetAttribute(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_CONST_STRING strReturnedAttribute;

	/* Need to free these */
	DRM_CONST_STRING strAttributeName, strAttributeNameBackup, strExpectedData;

	strExpectedData.pwszString =
	strAttributeName.pwszString = 
	strAttributeNameBackup.pwszString = NULL;

	ChkArg(argc == 3 || (argc == 4 && argv[2] && argv[3]));
	ChkArg(argv[1]);

	/* Set the attribute name */
	if (argv[0]) {
		MakeDRMString(&strAttributeName, argv[0]);
		ChkDR(DupDRMString(&strAttributeNameBackup, &strAttributeName));
	}

	ChkDR(DRM_HDR_GetAttribute(
		g_pStrContentHeader,
		argv[0]? &strAttributeName: NULL,
		OEM_atol(argv[1]),
		argv[2]? &strReturnedAttribute: NULL, 0));

	/* verify the content string is intact */
	if (g_pStrContentHeader && DRM_wcsncmp(g_strContentHeader.pwszString, g_strContentHeaderBackup.pwszString, g_strContentHeaderBackup.cchString))
		ChkDR(DRM_E_FAIL);

	/* verify the attribute name is intact */
	if (argv[0] && DRM_wcsncmp(strAttributeName.pwszString, strAttributeNameBackup.pwszString, strAttributeNameBackup.cchString))
		ChkDR(DRM_E_FAIL);

	/* verify the expected return data */
	if (argc > 3) {
		MakeDRMString(&strExpectedData, argv[3]);
		if (DRM_wcsncmp(strReturnedAttribute.pwszString, strExpectedData.pwszString, strReturnedAttribute.cchString))
			dr = DRM_S_FALSE;
	}
ErrorExit:
	DX_VOS_MemFree((DRM_WCHAR*)strExpectedData.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)strAttributeName.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)strAttributeNameBackup.pwszString);
	return dr;
}

/*	Test API DRM_HDR_GetUplink
	argv[0]: uplink index to retrieve
	argv[1]: expected uplink KID or NULL
*/
DRM_RESULT TestContentHeaderGetUplink(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_DWORD dwUplinkNumber;
	DRM_CONST_STRING szKID;

	ChkArg(argc == 2 && argv[0]);
	dwUplinkNumber = OEM_atol(argv[0]);

	ChkDR(DRM_HDR_GetUplink(
		g_pStrContentHeader,
		dwUplinkNumber,
		argv[1]? &szKID: NULL));

	/* verify the content string is intact */
	if (g_pStrContentHeader && DRM_wcsncmp(g_strContentHeader.pwszString, g_strContentHeaderBackup.pwszString, g_strContentHeaderBackup.cchString))
		ChkDR(DRM_E_FAIL);

	if (argv[1] && CompDRMString(&szKID, argv[1])) /* verify the retrieved uplink KID */
		dr = DRM_S_FALSE;
ErrorExit:
	return dr;
}

/*
BEGIN_APIMAP(RefHeaderTest_ansi, "header")
	API_ENTRY(TestLoadHeader)
	API_ENTRY(TestContentHeaderGetUplink)
	API_ENTRY(TestContentHeaderGetAttribute)
	API_ENTRY(TestContentHeaderVerify)
END_APIMAP
*/

