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

//#include <stdlib.h>
// #include <stdio.h>
// #include <string.h>
#include "DX_VOS_String.h"
#include "DX_VOS_Utils.h"
#include "drmcommon.h"
#include "drmlicense.h"
#include "drmcontextsizes.h"    
#include "drmdevcert.h"
#include "drmxmlparser.h"

#include "tclib.h"
#include "tstutils.h"
#include "tOEMIMP.h"

DRM_CONST_STRING g_dstrDevCert;
long g_secondsForward;

/*	Test API: DRM_DCP_GetAttribute
	argv[0]: status of devcert: NORMAL, NULL
	argv[1]: eDRM_DEVCERT_ATTRIBUTES value
	argv[2]: expected return node value, IGNORE or NULL
	argv[3]: expected return value, IGNORE or NULL
*/
DRM_RESULT TEST_API_DevCertGetAttribute(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_CONST_STRING dstrRetNode, dstrRetVal;

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

	ChkDR(DRM_DCP_GetAttribute(argv[0]? &g_dstrDevCert: NULL,
		OEM_atol(argv[1]),
		argv[2]? &dstrRetNode: NULL,
		argv[3]? &dstrRetVal: NULL));

	/* Now compare the return node to the expected node */
	if (argv[2] && DX_VOS_StrCmp(argv[2], "IGNORE") && CompDRMString(&dstrRetNode, argv[2])) {
		((DRM_WCHAR*)dstrRetNode.pwszString)[dstrRetNode.cchString] = 0;
		Log("UNEXPECTEDNODE", "Retrieved=%S,Expecting=%s", dstrRetNode.pwszString, argv[2]);
		dr = DRM_S_FALSE; /* Not matched! */
		goto ErrorExit;
	}

	/* Now compare the return value to the expected value */
	if (argv[3] && DX_VOS_StrCmp(argv[3], "IGNORE") && CompDRMString(&dstrRetVal, argv[3])) {
		((DRM_WCHAR*)dstrRetVal.pwszString)[dstrRetVal.cchString] = 0;
		Log("UNEXPECTEDVALUE", "Retrieved=%S,Expecting=%s", dstrRetVal.pwszString, argv[3]);
		dr = DRM_S_FALSE; /* Not matched! */
		goto ErrorExit;
	}

ErrorExit:
	return dr;
}

/*	Test API DRM_DCP_VerifyDeviceCert
	argv[0]: devcert status: NORMAL or NULL, EMPTY
	argv[1]: verify flag
	argv[2]: crypto context status: NORMAL or NULL
*/
DRM_RESULT TEST_API_DevCertVerifyDeviceCert(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_CRYPTO_CONTEXT *pCrypto = NULL;
	DRM_CONST_STRING dstrEmpty = {0}, *pdstrDevcert = NULL;

	ChkArg(argc == 3 && argv[1]);
	if (argv[0])
		pdstrDevcert = *(argv[0])? &g_dstrDevCert: &dstrEmpty;

	if (argv[2]) {
		ChkMem(pCrypto = (DRM_CRYPTO_CONTEXT*)DX_VOS_MemMalloc(sizeof(DRM_CRYPTO_CONTEXT)));
	}

	ChkDR(DRM_DCP_VerifyDeviceCert(pdstrDevcert, OEM_atol(argv[1]), pCrypto));

ErrorExit:
	DX_VOS_MemFree(pCrypto);
	return dr;
}

/* Modify the global g_dcStruct for other tests. 
	argv[0]: operation: Remove, Modify
	argv[1]: node name
	argv[2]: attribute name
	argv[3]: path
*/
DRM_RESULT TEST_ChangeDevcertNode(long argc, char **argv)
{
	DRM_RESULT dr;
	DRM_CONST_STRING dstrNode = {0}, dstrAttr = {0}, dstrPath = {0};
	DRM_CONST_STRING dstrSubNode, dstrNodeToModify, dstrDataToModify;

	ChkArg(argc == 4 && argv[0]);

	MakeDRMString(&dstrNode, argv[1]);
	MakeDRMString(&dstrAttr, argv[2]);
	MakeDRMString(&dstrPath, argv[3]);

	/* Search the part to remove */
	ChkDR(DRM_XML_GetSubNode(&g_dstrDevCert, &dstrNode, argv[2]? &g_dstrAttributeType: NULL, &dstrAttr, 0, &dstrSubNode, NULL, 1));
	
	if (dstrPath.pwszString) {
		ChkDR(DRM_XML_GetSubNodeByPath(&dstrSubNode, &dstrPath, NULL, NULL, &dstrNodeToModify, &dstrDataToModify, g_wchForwardSlash));  
	} else
		DX_VOS_FastMemCpy(&dstrNodeToModify, &dstrSubNode, sizeof(dstrDataToModify));

	if (!DX_VOS_StrCmp(argv[0], "Remove")) {
		DRM_STRING dstrDevcert;
		DX_VOS_FastMemCpy(&dstrDevcert, &g_dstrDevCert, sizeof(dstrDevcert));
		ChkDR(DRM_UTL_StringRemoveSubString(&dstrDevcert, &dstrNodeToModify));
		DX_VOS_FastMemCpy(&g_dstrDevCert, &dstrDevcert, sizeof(g_dstrDevCert));
	
	} else if (!DX_VOS_StrCmp(argv[0], "Modify")) {
		ChkArg(dstrDataToModify.pwszString);
		((DRM_WCHAR*)dstrDataToModify.pwszString)[0]++;
	}
ErrorExit:
	DX_VOS_MemFree((DRM_WCHAR*)dstrNode.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)dstrAttr.pwszString);
	DX_VOS_MemFree((DRM_WCHAR*)dstrPath.pwszString);
	return dr;
}

/* roll forward the machine clock in years to expire everything
	argv[0]: years to roll forward
*/
DRM_RESULT TEST_RollForwardClockInYears(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	long lSeconds;

	ChkArg(argc == 1 && argv[0]);
	lSeconds = OEM_atol(argv[0]) * 365 * 24 * 60 * 60;
	dr = tChangeSystemTime(lSeconds);
	g_secondsForward += lSeconds;
ErrorExit:
	return dr;
}

DRM_RESULT DCP_PreTestCase(long lTCID, char *strTCName)
{
    DRM_RESULT dr = DRM_SUCCESS;

	g_secondsForward = 0;
	g_dstrDevCert.pwszString = NULL;
    /*DX: added full path*/
	ChkArg(LoadTestFile(NULL, "devcert.dat", (DRM_BYTE **)(&((g_dstrDevCert.pwszString))), (DRM_DWORD *)&g_dstrDevCert.cchString));

	g_dstrDevCert.cchString /= sizeof(DRM_WCHAR);
ErrorExit:
    return dr;
}

DRM_RESULT DCP_PostTestCase(long lTCID, char *strTCName)
{
	/* reset system clock to current year */
	tChangeSystemTime(-g_secondsForward);
	g_secondsForward = 0;

	DX_VOS_MemFree((DRM_WCHAR*)g_dstrDevCert.pwszString);
	return DRM_SUCCESS;
}

/*
IMPLEMENT_DEFAULT_WARPTEST

BEGIN_APIMAP(DeviceDevcertTest_ansi, "dcParser")
	API_ENTRY(TEST_API_DevCertGetAttribute)
	API_ENTRY(TEST_API_DevCertVerifyDeviceCert)
	API_ENTRY(TEST_ChangeDevcertNode)
	API_ENTRY(TEST_RollForwardClockInYears)
END_APIMAP
*/
