
#ifdef DX_CC5_SEP_PLAT
#include "MW_ATP_define_flags.h"
#endif
#include "DX_VOS_BaseTypes.h"
#include "DX_VOS_Stdio.h"
#include "DX_VOS_Utils.h"
#include "DX_VOS_Mem.h"
#include "DX_VOS_String.h"
#include "DX_VOS_File.h"

#include "drmcommon.h"
#include "apiParams.h"
#include "tstparams.h"

extern DRM_RESULT  WMDRM_BlackBoxAPITests();
extern DRM_RESULT  WMDRM_CryptoAPITests();
extern DRM_RESULT WMDRM_DevCertParserTests();
extern DRM_RESULT  WMDRM_DevCertGenerationTests();
extern DRM_RESULT  WMDRM_DevStoreTests();
extern DRM_RESULT  WMDRM_DRMManagerTests();
extern DRM_RESULT  WMDRM_ExpressionEvalTests();
extern DRM_RESULT  WMDRM_HDSTests();
extern DRM_RESULT  WMDRM_HeaderTests();
extern DRM_RESULT  WMDRM_LicenseEvalTests();
extern DRM_RESULT  WMDRM_LicenseParserTests();
extern DRM_RESULT  WMDRM_LicenseStoreTests();
extern DRM_RESULT  WMDRM_MeteringTests();
extern DRM_RESULT  WMDRM_SecureStoreTests();
extern DRM_RESULT  WMDRM_SecureClockTests();
extern DRM_RESULT  WMDRM_SyncListTests();
extern DRM_RESULT  WMDRM_UtilsTests();
extern DRM_RESULT  WMDRM_ViewRightsTests();
extern DRM_RESULT  WMDRM_XMLBuilderTests();
extern DRM_RESULT  WMDRM_XMLParserTests();

extern void WMDRM_TestRun(WMDRMRunInfoPtr_t tstInfo_ptr);

PRIVKEY testPrivateKey = {0xc0,0xb4,0x48,0x52,
							 0xe7,0x63,0xfa,0x1e,
							 0x7e,0xd4,0xad,0xab,
							 0x4b,0x87,0x99,0xff,
							 0xbb,0x27,0x88,0x27};
#ifdef _DX_BLACK_BOX_SIM
extern DRM_RESULT DRM_API OEM_setActionGroupCertPrivKey(DRM_CHAR *    f_wrapKey );
#endif

static DxUint32_t g_testParam = WMDRM_ALL_TESTS_PARAM;

/**************** Editable Input *******************/

static DxBool_t _CheckCharOnDigit(DxChar ch)
{
    if ((0x30 <= ch) && (ch <= 0x39))
    {
        return DX_TRUE;
    }
    return DX_FALSE;
}

static DxBool_t _CheckCharOnCharacter(DxChar ch)
{
    if (   (('a' <= ch) && (ch <= 'z'))
        || (('A' <= ch) && (ch <= 'Z')))
    {
        return DX_TRUE;
    }
    return DX_FALSE;
}


DxChar _UserInput()
{
    DxInt_t ch = 0;
#ifdef DX_CC5_SEP_PLAT
	do
 	{
 		ch = DX_VOS_GetCh();
	} while((ch==' ')||(ch=='\r')||(ch=='\n')||(ch=='\t'));
	
	return ch;
#else
    DxUint32_t i = 0;
    DxChar str[WMDRM_MAX_LEN_INPUT_DIGIT] = {0};
    
    /*Was: while (ch != 0xD)*/
    while ('\r' != ch && '\n' != ch)
    {
        DxChar strPrint[2] = {0};

        ch = DX_VOS_GetCh();
        /*Was: if (0x8 == ch)*/

        if ('\b' == ch)
        {
            strPrint[0] = ch;
            DX_VOS_Printf(strPrint);
            DX_VOS_Printf(" ");
            DX_VOS_Printf(strPrint);
            if (i > 0)
            {
                --i;
                str[i] = 0;
            }
        }
        else if (((DX_TRUE == _CheckCharOnDigit(ch))              
               || (DX_TRUE == _CheckCharOnCharacter(ch)))
              && (i < sizeof(str)))
        {
            strPrint[0] = str[i] = ch;
            ++i;
            DX_VOS_Printf(strPrint);
        }
    }

    if (i > 0)
    {
        return str[0];
    }

    return WMDRM_ERROR_INPUT_UINT;
#endif
}


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

static void _UsageHelp()
{
    DX_VOS_Printf("\n****************************************************************\n");
    DX_VOS_Printf("To run different groups of tests several keys can be used (keys\n are not case sensitive):\n");
    DX_VOS_Printf("- bvt  - key is used to run only BVT tests from test menu\n");
    DX_VOS_Printf("- func - key is used to run only Functional tests from test menu\n");
    DX_VOS_Printf("- Key less style of execution is used to run All (BVT and Functional)\n tests from test menu\n\n");
    DX_VOS_Printf("Examples:\n\n");
    DX_VOS_Printf("wmdrm_tests.exe bvt\n");
    DX_VOS_Printf("wmdrm_tests.exe FUNC\n");
    DX_VOS_Printf("wmdrm_tests.exe\n");
    DX_VOS_Printf("****************************************************************\n");
}


/************************* Structs ******************************/
/**
*   _ParseCmdParams
*
*   @brief The function parses command line parameters
*
*   @param argc          [in] number of command line parameters
*   @param argv          [in] pointer to array of command line parameters
*   @param testFlag_ptr  [in] pointer to test switch flag variable
*
*   @return DRM_RESULT
*           - DRM_SUCCESS in case of success, otherwise DRM_S_FALSE
*/
static DRM_RESULT _ParseCmdParams(DxUint32_t argc, DxChar* argv[], DxUint32_t* testFlag_ptr)
{
    DRM_RESULT cmpResult = DRM_S_FALSE;
    DxUint32_t i = 0;

	/*case of calling from main menue without parameters */
	if(argc == 0x0)
	{
        cmpResult = DRM_SUCCESS;
        *testFlag_ptr = WMDRM_ALL_TESTS_PARAM;
        goto END_LABEL;
	}
    if (argc > 2)
    {
        cmpResult = DRM_S_FALSE;
        goto END_LABEL;
    }

    if (DX_NULL == argv[1])
    {
        cmpResult = DRM_SUCCESS;
        *testFlag_ptr = WMDRM_ALL_TESTS_PARAM;
        
        goto END_LABEL;
    }
    
    DX_VOS_StrToLower(argv[1], WMDRM_MAX_STRING_LEN);
    if (!DX_VOS_StrNCmp(WMDRM_BVT_TESTS_STR, argv[1], WMDRM_MAX_STRING_LEN))
    {
        cmpResult = DRM_SUCCESS;
        *testFlag_ptr = WMDRM_BVT_TESTS_PARAM;

        goto END_LABEL;
    }
    else if (!DX_VOS_StrNCmp(WMDRM_FUNC_TESTS_STR, argv[1], WMDRM_MAX_STRING_LEN))
    {
        cmpResult = DRM_SUCCESS;
        *testFlag_ptr = WMDRM_FUNC_TESTS_PARAM;

        goto END_LABEL;
    }
    else
    {
        cmpResult = DRM_S_FALSE;
        goto END_LABEL;
    }

END_LABEL:    
    return cmpResult;
}

DRM_RESULT WMDRM_TST_menu (DxUint32_t argc, DxChar* argv[])
{
    DxUint32_t TST_number = 0;
    DxUint8_t TST_input = 0;
    DxChar TST_inputBuf [4] = {0};
    DRM_RESULT testResult = DRM_SUCCESS;
	DRM_UINT wrapKeyLen = 32;


	DRM_CHAR  tBuff[32];

    WMDRMRunInfo_t TST_tc [] =
    {
        {'1', "Black Box APIs Tests", WMDRM_BlackBoxAPITests}
        , {'1', "Crypto APIs Tests", WMDRM_CryptoAPITests}
        , {'1', "Device certificate parser APIs Tests", WMDRM_DevCertParserTests}
        , {'1', "Device certificate generation", WMDRM_DevCertGenerationTests}
#if DRM_SUPPORT_DEVICESTORE
        , {'1', "Device store (DRM Core) APIs Tests", WMDRM_DevStoreTests}
#endif
        , {'1', "Top level exposed (DRM Manager) APIs Tests", WMDRM_DRMManagerTests}
        , {'1', "Expression evaluator (DRM Core) APIs Tests", WMDRM_ExpressionEvalTests}
        , {'1', "Low level hashed data store (DRM Core) APIs Tests", WMDRM_HDSTests}
        , {'1', "Header parser APIs to create challenge (DRM Core) Tests", WMDRM_HeaderTests}
        , {'1', "License evaluator (DRM Core) APIs Tests", WMDRM_LicenseEvalTests}
        , {'1', "License parser (DRM Core) APIs Tests", WMDRM_LicenseParserTests}
        , {'1', "License store (DRM Core) APIs Tests", WMDRM_LicenseStoreTests}
        , {'1', "Metering collection, meter challenge and process reset Tests", WMDRM_MeteringTests}
        , {'1', "Secure Store (DRM Core) APIs Tests", WMDRM_SecureStoreTests}
#if DRM_SUPPORT_SECURE_CLOCK
        , {'1', "Secure Clock APIs Tests", WMDRM_SecureClockTests}
#endif
        , {'1', "Sync challenge Tests", WMDRM_SyncListTests}
        , {'1', "CRT and other utilities (DRM Core) Tests", WMDRM_UtilsTests}
        , {'1', "Top level view rights (DRM Core) APIs Tests", WMDRM_ViewRightsTests}
        , {'1', "XML Builder (DRM Core) APIs Tests", WMDRM_XMLBuilderTests}
        , {'1', "XML Parser  (DRM Core) APIs Tests", WMDRM_XMLParserTests}
        , {'1', "", NULL}
    };


#ifdef _DX_BLACK_BOX_SIM
	/*only for simulation*/
	/*It is needed only for the tests because some tests initialization use
	the clear private*/
	OEM_setActionGroupCertPrivKey((DRM_CHAR*)&testPrivateKey);
#endif

	/*Initialize the private key in the CC5 system*/
	OEM_setGroupCertPrivKey(TRUE,&testPrivateKey,&wrapKeyLen,tBuff);

    TST_number = 1;
    while (NULL != TST_tc[TST_number].TST_method)
    {
        DxChar ch = TST_tc[TST_number - 1].choiceChar;
        TST_tc[TST_number].choiceChar = ch;
        ++TST_tc[TST_number].choiceChar;
        
        if (   (TST_tc[TST_number].choiceChar > '9')
            && (TST_tc[TST_number].choiceChar < 'A'))
        {
            TST_tc[TST_number].choiceChar = 'A';
        }
        ++TST_number;
    }

    if (DX_SUCCESS != _ParseCmdParams(argc, argv, &g_testParam))
    {
        testResult = DRM_S_FALSE;
        _UsageHelp();
        return 0;
    }

    do 
    {
        DX_VOS_Printf("\t\t\t-- DISCRETIX LTD 2008 --\n");
        DX_VOS_Printf("\t\t\t WMDRM Tests Ver 1.0.0\n");
        
        switch(g_testParam)
        {
        case WMDRM_ALL_TESTS_PARAM: DX_VOS_Printf("\t\t\tTests to run: All Tests\n"); 
        	break;
        case WMDRM_BVT_TESTS_PARAM: DX_VOS_Printf("\t\t\tTests to run: BVT Tests Only\n");
        	break;
        case WMDRM_FUNC_TESTS_PARAM: DX_VOS_Printf("\t\t\tTests to run: Functional Tests Only\n");
            break;
        default: DX_VOS_Printf("\tTests to run: All Tests\n"); 
            break;
        }
    
        DX_VOS_Printf("\n    -- [ Main Tests Menu ] --\n");

        TST_number = 0;
        while (NULL != TST_tc[TST_number].TST_method)
        {
            DX_VOS_Printf("\n[%c] - %s", TST_tc[TST_number].choiceChar, TST_tc[TST_number].TST_descr);
            ++TST_number;
        }
        DX_VOS_Printf("\n[T] - Run All Tests");
        DX_VOS_Printf("\n[Z] - Exit");
        DX_VOS_Printf("\n\nEnter Test Number: ");

        TST_input = _UserInput();

        if (WMDRM_ERROR_INPUT_UINT != TST_input)
        {
            DX_VOS_StrToUpper(&TST_input, sizeof(TST_input));
            switch(TST_input)
            {
            case 'T': /*run all tests*/
                TST_number = 0;

                while (NULL != TST_tc[TST_number].TST_method)
                {
                    WMDRM_TestRun(&TST_tc[TST_number]);
                    ++TST_number;
                }
            	break;
            case 'Z': /*exit*/
                return 0;
            default:
                TST_number = 0;
                while ((NULL != TST_tc[TST_number].TST_method) && (TST_input != TST_tc[TST_number].choiceChar))
                {
                    ++TST_number;
                }
                
                if (NULL != TST_tc[TST_number].TST_method)
                {

                    WMDRM_TestRun(&TST_tc[TST_number]);
                }
                else
                {
                    DX_VOS_Printf("\n* Error in test selection [%c]ASCII(%d)\n",TST_input,(DxUint32_t)TST_input);
                }
                break;
            }
        }
        
    } while(TST_input != 0);

    return 0;
}




