/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
#ifndef PVMF_MP4FFPARSER_NODE_H_INCLUDED
#include "pvmf_mp4ffparser_node.h"
#endif
#ifndef OSCL_MIME_STRING_UTILS_H_INCLUDED
#include "pv_mime_string_utils.h"
#endif
#ifndef PVMI_FILEIO_KVP_H_INCLUDED
#include "pvmi_fileio_kvp.h"
#endif

///////////////////////////////////////////////////////////////////////////////
//
// Capability and config interface related constants and definitions
//   - based on pv_player_engine.h
//
///////////////////////////////////////////////////////////////////////////////
struct MP4ParserNodeKeyStringData
{
    char iString[64];
    PvmiKvpType iType;
    PvmiKvpValueType iValueType;
};


// The number of characters to allocate for the key string
#define MP4CONFIG_KEYSTRING_SIZE 128

//The base selection keys for file IO,leading tag needs to be fileio
static const MP4ParserNodeKeyStringData MP4ParserNodeConfig_FileIO_Keys[] =
{
    {"pv-cache-size", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"async-read-buffer-size", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"logger-enable", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL},
    {"logger-stats-enable", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_BOOL},
    {"native-access-mode", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32},
    {"file-handle", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_KSV}
};

//The base selection keys for file IO,leading tag needs to be x-pvmf\net
static const MP4ParserNodeKeyStringData MP4ParserNodeConfig_Net_Keys[] =
{
    {"delay", PVMI_KVPTYPE_VALUE, PVMI_KVPVALTYPE_UINT32}
};

static const uint MP4ParserNodeConfig_Num_FileIO_Keys =
    (sizeof(MP4ParserNodeConfig_FileIO_Keys) /
     sizeof(MP4ParserNodeKeyStringData));

static const uint MP4ParserNodeConfig_Num_Net_Keys =
    (sizeof(MP4ParserNodeConfig_Net_Keys) /
     sizeof(MP4ParserNodeKeyStringData));


enum BaseFileIOKeys_IndexMapType
{
    PV_CACHE_SIZE = 0,
    ASYNC_READ_BUFFER_SIZE,
    BASEKEY_PVLOGGER_ENABLE,
    PVLOGGER_STATS_ENABLE,
    NATIVE_ACCESS_MODE,
    FILE_HANDLE,
};

enum BaseNetKeys_IndexMapType
{
    DELAY = 0
};



///////////////////////////////////////////////////////////////////////////////

PVMFStatus PVMFMP4FFParserNode::getParametersSync(
    PvmiMIOSession aSession, PvmiKeyType aIdentifier,
    PvmiKvp*& aParameters, int& aNumParamElements,
    PvmiCapabilityContext aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);

    // Initialize the output parameters
    aNumParamElements = 0;
    aParameters = NULL;

    // Count the number of components and parameters in the key
    int compcount = pv_mime_string_compcnt(aIdentifier);
    // Retrieve the first component from the key string
    char* compstr = NULL;
    pv_mime_string_extract_type(0, aIdentifier, compstr);

    iBaseKey = INVALID;

    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("fileio")) < 0) || compcount < 2)
    {
        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
        {

            // First component should be "fileio" or "x-pvmf" and there must
            // be at least two components to go past fileio and x-pvmf
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::getParametersSync() Invalid key string"));
            return PVMFErrArgument;

        }
        else
        {
            // Retrieve the second component from the key string
            pv_mime_string_extract_type(1, aIdentifier, compstr);

            // Check if it is key string for streaming
            if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) < 0)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::getParametersSync() Unsupported key"));
                return PVMFFailure;
            }
            iBaseKey = NET;
        }
    }
    else
    {
        //Since the key string matches that of fileio
        iBaseKey = FILE_IO;
    }

    //If the leading tag is fileio then component count should be 2
    if ((iBaseKey == FILE_IO) && (compcount == 2))
    {
        //BaseKey's leading tag is fileio;
        pv_mime_string_extract_type(1, aIdentifier, compstr);

        // Determine what is requested
        PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
        if (reqattr == PVMI_KVPATTR_UNKNOWN)
        {
            reqattr = PVMI_KVPATTR_CUR;
        }
        uint i;
        for (i = 0; i < MP4ParserNodeConfig_Num_FileIO_Keys; i++)
        {
            if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_FileIO_Keys[i].iString)) >= 0)
            {
                break;
            }
        }

        if (i == MP4ParserNodeConfig_Num_FileIO_Keys)
        {
            // no match found
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::getParametersSync() Unsupported key"));
            return PVMFErrNoMemory;
        }

        PVMFStatus retval = GetConfigParameter(aParameters, aNumParamElements, i, reqattr);
        if (retval != PVMFSuccess)
        {
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::getParametersSync() "
                                          "Retrieving mp4 parser node parameter failed"));
            return retval;
        }
    }
    else if ((iBaseKey == NET) && ((compcount == 2) || (compcount == 3)))
    {
        //	//BaseKey's leading tag is x-pvmf\net

        if (compcount == 2)
        {
            // Since key is "x-pvmf/net" return all
            // nodes available at this level. Ignore attribute
            // since capability is only allowed

            // Allocate memory for the KVP list
            aParameters = (PvmiKvp*)oscl_malloc(MP4ParserNodeConfig_Num_Net_Keys * sizeof(PvmiKvp));
            if (aParameters == NULL)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::getParametersSync() Memory allocation for KVP failed"));
                return PVMFErrNoMemory;
            }
            oscl_memset(aParameters, 0, MP4ParserNodeConfig_Num_Net_Keys*sizeof(PvmiKvp));
            // Allocate memory for the key strings in each KVP
            PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(MP4ParserNodeConfig_Num_Net_Keys * MP4CONFIG_KEYSTRING_SIZE * sizeof(char));
            if (memblock == NULL)
            {
                oscl_free(aParameters);
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::getParametersSync() Memory allocation for key string failed"));
                return PVMFErrNoMemory;
            }
            oscl_strset(memblock, 0, MP4ParserNodeConfig_Num_Net_Keys*MP4CONFIG_KEYSTRING_SIZE*sizeof(char));
            // Assign the key string buffer to each KVP
            int32 j;
            for (j = 0; j < MP4ParserNodeConfig_Num_Net_Keys; ++j)
            {
                aParameters[j].key = memblock + (j * MP4CONFIG_KEYSTRING_SIZE);
            }
            // Copy the requested info
            for (j = 0; j < MP4ParserNodeConfig_Num_Net_Keys; ++j)
            {
                oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/net/"), 11);
                oscl_strncat(aParameters[j].key, MP4ParserNodeConfig_Net_Keys[j].iString, oscl_strlen(MP4ParserNodeConfig_Net_Keys[j].iString));
                oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6);
                switch (MP4ParserNodeConfig_Net_Keys[j].iType)
                {
                    case PVMI_KVPTYPE_AGGREGATE:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING));
                        break;

                    case PVMI_KVPTYPE_POINTER:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING));
                        break;

                    case PVMI_KVPTYPE_VALUE:
                    default:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING));
                        break;
                }
                oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9);
                switch (MP4ParserNodeConfig_Net_Keys[j].iValueType)
                {
                    case PVMI_KVPVALTYPE_RANGE_INT32:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
                        break;

                    case PVMI_KVPVALTYPE_KSV:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
                        break;

                    case PVMI_KVPVALTYPE_CHARPTR:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING), oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
                        break;

                    case PVMI_KVPVALTYPE_BOOL:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
                        break;

                    case PVMI_KVPVALTYPE_UINT32:
                    default:
                        oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
                        break;
                }
                aParameters[j].key[MP4CONFIG_KEYSTRING_SIZE-1] = 0;
            }

            aNumParamElements = MP4ParserNodeConfig_Num_Net_Keys;
        }
        else if (compcount == 3)
        {
            pv_mime_string_extract_type(2, aIdentifier, compstr);

            // Determine what is requested
            PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier);
            if (reqattr == PVMI_KVPATTR_UNKNOWN)
            {
                reqattr = PVMI_KVPATTR_CUR;
            }
            int i;
            for (i = 0; i < MP4ParserNodeConfig_Num_Net_Keys; i++)
            {
                if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_Net_Keys[i].iString)) >= 0)
                {
                    break;
                }
            }

            if (i == MP4ParserNodeConfig_Num_Net_Keys)
            {
                // no match found
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFMP4FFParserNode::getParametersSync() Unsupported key"));
                return PVMFErrNoMemory;
            }

            PVMFStatus retval = GetConfigParameter(aParameters, aNumParamElements, i, reqattr);
            if (retval != PVMFSuccess)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
                                (0, "PVMFMP4FFParserNode::getParametersSync() "
                                 "Retrieving streaming manager parameter failed"));
                return retval;
            }
        }
    }
    else
    {
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::getParametersSync() Unsupported key"));
        return PVMFErrArgument;
    }

    return PVMFSuccess;
}

PVMFStatus PVMFMP4FFParserNode::releaseParameters(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    OSCL_UNUSED_ARG(aSession);
    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::releaseParameters() In"));

    if (aParameters == NULL || num_elements < 1)
    {
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::releaseParameters() KVP list is NULL or number of elements is 0"));
        return PVMFErrArgument;
    }

    int32 compcount = pv_mime_string_compcnt(aParameters[0].key);

    // Retrieve the first component from the key string
    char* compstr = NULL;

    pv_mime_string_extract_type(0, aParameters[0].key, compstr);

    BaseKeys_SelectionType basekey = INVALID;

    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("fileio")) < 0) || compcount < 2)
    {
        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) < 0) || compcount < 2)
        {
            // First component should be "fileio" or "x-pvmf" and there must
            // be at least two components to go past fileio and x-pvmf
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::getParametersSync() Invalid key string"));
            return PVMFErrArgument;
        }
        else
        {
            // Retrieve the second component from the key string
            pv_mime_string_extract_type(1, aParameters[0].key, compstr);

            // Check if it is key string for streaming
            if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) < 0)
            {
                PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFMP4FFParserNode::getParametersSync() Unsupported key"));
                return PVMFErrArgument;
            }
            basekey = NET;
        }
    }
    else
    {
        //Since the key string matches that of fileio
        basekey = FILE_IO;
    }

    pv_mime_string_extract_type(0, aParameters[0].key, compstr);

    //It does not effect in releasing memory what are the base keys either fileio or x-pvmf.
    if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("fileio")) >= 0) || (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) >= 0))
    {
        // Go through each KVP and release memory for value if allocated from heap
        for (int32 i = 0; i < num_elements; ++i)
        {
            // Next check if it is a value type that allocated memory
            PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key);
            if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN)
            {
                PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key);
                if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
                {
                    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::releaseParameters() Valtype not specified in key string"));
                    return PVMFErrArgument;
                }

                if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pChar_value);
                    aParameters[i].value.pChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_WCHARPTR && aParameters[i].value.pWChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pWChar_value);
                    aParameters[i].value.pWChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL)
                {
                    oscl_free(aParameters[i].value.pChar_value);
                    aParameters[i].value.pChar_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL)
                {
                    oscl_free(aParameters[i].value.key_specific_value);
                    aParameters[i].value.key_specific_value = NULL;
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_INT32 && aParameters[i].value.key_specific_value != NULL)
                {
                    range_int32* ri32 = (range_int32*)aParameters[i].value.key_specific_value;
                    aParameters[i].value.key_specific_value = NULL;
                    oscl_free(ri32);
                }
                else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL)
                {
                    range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value;
                    aParameters[i].value.key_specific_value = NULL;
                    oscl_free(rui32);
                }
            }
        }

        oscl_free(aParameters[0].key);

        // Free memory for the parameter list
        oscl_free(aParameters);
        aParameters = NULL;
    }
    else
    {
        // Unknown key string
        return PVMFErrArgument;
    }

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::releaseParameters() Out"));
    return PVMFSuccess;
}

void PVMFMP4FFParserNode::createContext(PvmiMIOSession aSession,
                                        PvmiCapabilityContext& aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}

void PVMFMP4FFParserNode::setContextParameters(PvmiMIOSession aSession,
        PvmiCapabilityContext& aContext,
        PvmiKvp* aParameters,
        int num_parameter_elements)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_parameter_elements);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}

void PVMFMP4FFParserNode::DeleteContext(PvmiMIOSession aSession,
                                        PvmiCapabilityContext& aContext)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aContext);
    // not supported
    OSCL_LEAVE(PVMFErrNotSupported);
}


void PVMFMP4FFParserNode::setParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters,
        int num_elements, PvmiKvp* &aRet_kvp)
{
    OSCL_UNUSED_ARG(aSession);

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() In"));


    // Go through each parameter
    for (int paramind = 0; paramind < num_elements; ++paramind)
    {
        // Count the number of components and parameters in the key
        int compcount = pv_mime_string_compcnt(aParameters[paramind].key);

        // Retrieve the first component from the key string
        char* compstr = NULL;
        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);

        // First check if it is key string for the mp4 parser node
        if (pv_mime_strcmp(compstr, _STRLIT_CHAR("fileio")) >= 0)
        {
            iBaseKey = FILE_IO;
            if (compcount == 2)
            {
                pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
                uint i;
                for (i = 0; i < MP4ParserNodeConfig_Num_FileIO_Keys; i++)
                {
                    char *x = (char*)MP4ParserNodeConfig_FileIO_Keys[i].iString;
                    if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_FileIO_Keys[i].iString)) >= 0)
                    {
                        break;
                    }
                }

                if (MP4ParserNodeConfig_Num_FileIO_Keys == i)
                {
                    // invalid third component
                    aRet_kvp = &aParameters[paramind];
                    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
                    return;
                }

                // Verify and set the passed-in setting
                PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], true);
                if (retval != PVMFSuccess)
                {
                    aRet_kvp = &aParameters[paramind];
                    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Setting "
                                                  "parameter %d failed", paramind));
                    return;
                }
            }
            else
            {
                // Do not support more than 2 components right now
                aRet_kvp = &aParameters[paramind];
                PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
                return;
            }
        }
        else if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) >= 0)
        {
            if (compcount == 3)
            {
                // Retrieve the second component from the key string
                pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
                // First check if it is key string for the streaming manager
                if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
                {
                    iBaseKey = NET;
                    int i;
                    //Extract the third component from the key string
                    pv_mime_string_extract_type(2, aParameters[paramind].key, compstr);
                    for (i = 0; i < MP4ParserNodeConfig_Num_Net_Keys; i++)
                    {
                        char *x = (char*)MP4ParserNodeConfig_Net_Keys[i].iString;
                        if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_Net_Keys[i].iString)) >= 0)
                        {
                            break;
                        }
                    }

                    if (MP4ParserNodeConfig_Num_Net_Keys == i)
                    {
                        // invalid third component
                        aRet_kvp = &aParameters[paramind];
                        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
                        return;
                    }

                    // Verify and set the passed-in setting
                    PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], true);
                    if (retval != PVMFSuccess)
                    {
                        aRet_kvp = &aParameters[paramind];
                        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Setting "
                                                      "parameter %d failed", paramind));
                        return;
                    }
                }
                else
                {
                    // Unknown key string
                    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
                    return;
                }
            }
            else
            {
                // Do not support more than 3 components right now
                aRet_kvp = &aParameters[paramind];
                PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
                return;
            }
        }
        else
        {
            // Unknown key string
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Unsupported key"));
            return;
        }
    }

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::setParametersSync() Out"));
}

PVMFCommandId PVMFMP4FFParserNode::setParametersAsync(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements,
        PvmiKvp*& aRet_kvp,
        OsclAny* context)
{
    OSCL_UNUSED_ARG(aSession);
    OSCL_UNUSED_ARG(aParameters);
    OSCL_UNUSED_ARG(num_elements);
    OSCL_UNUSED_ARG(aRet_kvp);
    OSCL_UNUSED_ARG(context);
    // not supported
    OSCL_LEAVE(OsclErrNotSupported);
    // to satisfy compiler, need to return
    return 0;
}

uint32 PVMFMP4FFParserNode::getCapabilityMetric(PvmiMIOSession aSession)
{
    OSCL_UNUSED_ARG(aSession);
    return 0;
}

PVMFStatus PVMFMP4FFParserNode::verifyParametersSync(PvmiMIOSession aSession,
        PvmiKvp* aParameters,
        int num_elements)
{
    OSCL_UNUSED_ARG(aSession);

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::verifyParametersSync() In"));

    if (aParameters == NULL || num_elements < 1)
    {
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::verifyParametersSync() Passed in parameter invalid"));
        return PVMFErrArgument;
    }

    // Go through each parameter and verify
    for (int32 paramind = 0; paramind < num_elements; ++paramind)
    {
        // Retrieve the first component from the key string
        char* compstr = NULL;

        // Retrieve the second component from the key string
        pv_mime_string_extract_type(0, aParameters[paramind].key, compstr);

        // First check if it is key string for this node
        if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("fileio")) >= 0))
        {
            iBaseKey = FILE_IO;
            pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
            int i;
            for (i = 0; i < MP4ParserNodeConfig_Num_FileIO_Keys; i++)
            {
                if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_FileIO_Keys[i].iString)) >= 0)
                {
                    break;
                }
            }

            if (MP4ParserNodeConfig_Num_FileIO_Keys == i)
            {
                return PVMFErrArgument;
            }

            // Verify the passed-in player setting
            PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], false);
            if (retval != PVMFSuccess)
            {
                PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
                return retval;
            }
        }
        // First check if it is key string for this node
        else if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf")) >= 0))
        {
            pv_mime_string_extract_type(1, aParameters[paramind].key, compstr);
            if (pv_mime_strcmp(compstr, _STRLIT_CHAR("net")) >= 0)
            {
                iBaseKey = NET;
                int i;
                pv_mime_string_extract_type(2, aParameters[paramind].key, compstr);
                for (i = 0; i < MP4ParserNodeConfig_Num_Net_Keys; i++)
                {
                    if (pv_mime_strcmp(compstr, (char*)(MP4ParserNodeConfig_Net_Keys[i].iString)) >= 0)
                    {
                        break;
                    }
                }

                if (MP4ParserNodeConfig_Num_Net_Keys == i)
                {
                    return PVMFErrArgument;
                }

                // Verify the passed-in player setting
                PVMFStatus retval = VerifyAndSetConfigParameter(i, aParameters[paramind], false);
                if (retval != PVMFSuccess)
                {
                    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoCapConfigVerifyParameters() Verifying parameter %d failed", paramind));
                    return retval;
                }
            }
            else
            {
                // Unknown key string
                return PVMFErrArgument;
            }
        }
        else
        {
            // Unknown key string
            return PVMFErrArgument;
        }

    }

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoCapConfigVerifyParameters() Out"));
    return PVMFSuccess;
}

PVMFStatus PVMFMP4FFParserNode::GetConfigParameter(PvmiKvp*& aParameters,
        int& aNumParamElements,
        int32 aIndex, PvmiKvpAttr reqattr)
{
    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() In"));

    aNumParamElements = 0;

    // Allocate memory for the KVP
    aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
    if (aParameters == NULL)
    {
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() Memory allocation for KVP failed"));
        return PVMFErrNoMemory;
    }
    oscl_memset(aParameters, 0, sizeof(PvmiKvp));

    // Allocate memory for the key string in KVP
    PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(MP4CONFIG_KEYSTRING_SIZE * sizeof(char));
    if (memblock == NULL)
    {
        oscl_free(aParameters);
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() Memory allocation for key string failed"));
        return PVMFErrNoMemory;
    }
    oscl_strset(memblock, 0, MP4CONFIG_KEYSTRING_SIZE*sizeof(char));

    // Assign the key string buffer to KVP
    aParameters[0].key = memblock;

    // Copy the key string
    if (iBaseKey == FILE_IO)
    {
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR("fileio/"), 7);
        oscl_strncat(aParameters[0].key, MP4ParserNodeConfig_FileIO_Keys[aIndex].iString,
                     oscl_strlen(MP4ParserNodeConfig_FileIO_Keys[aIndex].iString));
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
        switch (MP4ParserNodeConfig_FileIO_Keys[aIndex].iValueType)
        {
            case PVMI_KVPVALTYPE_RANGE_INT32:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
                break;

            case PVMI_KVPVALTYPE_KSV:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
                break;

            case PVMI_KVPVALTYPE_CHARPTR:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
                break;

            case PVMI_KVPVALTYPE_WCHARPTR:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_WCHARPTR_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING));
                break;

            case PVMI_KVPVALTYPE_BOOL:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
                break;

            case PVMI_KVPVALTYPE_UINT32:
            default:
                if (reqattr == PVMI_KVPATTR_CAP)
                {
                    oscl_strncat(aParameters[0].key,
                                 _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING),
                                 oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
                }
                else
                {
                    oscl_strncat(aParameters[0].key,
                                 _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING),
                                 oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
                }
                break;
        }
        aParameters[0].key[MP4CONFIG_KEYSTRING_SIZE-1] = 0;

        // Copy the requested info
        switch (aIndex)
        {
            case PV_CACHE_SIZE:
                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    aParameters[0].value.uint32_value = iCacheSize;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    // Return default
                    aParameters[0].value.uint32_value = DEFAULT_CAHCE_SIZE;
                }
                else
                {
                    // Return capability
                    range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
                    if (rui32 == NULL)
                    {
                        oscl_free(aParameters[0].key);
                        oscl_free(aParameters);
                        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() "
                                                      "Memory allocation for range uint32 failed"));
                        return PVMFErrNoMemory;
                    }
                    rui32->min = MIN_CACHE_SIZE;
                    rui32->max = MAX_CACHE_SIZE;
                    aParameters[0].value.key_specific_value = (void*)rui32;
                }
                break;
            case ASYNC_READ_BUFFER_SIZE:
                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    // Return current value
                    aParameters[0].value.uint32_value = iAsyncReadBuffSize;;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    // Return default
                    aParameters[0].value.uint32_value = DEFAULT_ASYNC_READ_BUFFER_SIZE;
                }
                else
                {
                    // Return capability
                    range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
                    if (rui32 == NULL)
                    {
                        oscl_free(aParameters[0].key);
                        oscl_free(aParameters);
                        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() "
                                                      "Memory allocation for range uint32 failed"));
                        return PVMFErrNoMemory;
                    }
                    rui32->min = MIN_ASYNC_READ_BUFFER_SIZE;
                    rui32->max = MAX_ASYNC_READ_BUFFER_SIZE;
                    aParameters[0].value.key_specific_value = (void*)rui32;
                }
                break;
            case BASEKEY_PVLOGGER_ENABLE:

                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    aParameters[0].value.bool_value = iPVLoggerEnableFlag;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    aParameters[0].value.bool_value = false;
                }
                else
                {
                    // Return capability - no concept of capability for keep alive interval
                    // do nothing
                }
                break;

            case PVLOGGER_STATS_ENABLE:
                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    aParameters[0].value.bool_value = iPVLoggerStateEnableFlag;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    aParameters[0].value.bool_value = false;
                }
                else
                {
                    // Return capability - no concept of capability for keep alive interval
                    // do nothing
                }
                break;
            case NATIVE_ACCESS_MODE:
                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    // Return current value
                    aParameters[0].value.uint32_value = iNativeAccessMode;;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    // Return default
                    aParameters[0].value.uint32_value = DEFAULT_NATIVE_ACCESS_MODE;
                }
                else
                {
                    // Return capability
                }
                break;



            default:
                // Invalid index
                oscl_free(aParameters[0].key);
                oscl_free(aParameters);
                PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoGetPlayerParameter() Invalid index to player parameter"));
                return PVMFErrArgument;
        }
    }
    else if (iBaseKey == NET)
    {
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/net/"), 11);
        oscl_strncat(aParameters[0].key, MP4ParserNodeConfig_Net_Keys[aIndex].iString,
                     oscl_strlen(MP4ParserNodeConfig_Net_Keys[aIndex].iString));
        oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20);
        switch (MP4ParserNodeConfig_Net_Keys[aIndex].iValueType)
        {
            case PVMI_KVPVALTYPE_RANGE_INT32:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_INT32_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_RANGE_INT32_STRING));
                break;

            case PVMI_KVPVALTYPE_KSV:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING));
                break;

            case PVMI_KVPVALTYPE_CHARPTR:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_CHARPTR_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING));
                break;

            case PVMI_KVPVALTYPE_WCHARPTR:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_WCHARPTR_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_WCHARPTR_STRING));
                break;

            case PVMI_KVPVALTYPE_BOOL:
                oscl_strncat(aParameters[0].key,
                             _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING),
                             oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING));
                break;

            case PVMI_KVPVALTYPE_UINT32:
            default:
                if (reqattr == PVMI_KVPATTR_CAP)
                {
                    oscl_strncat(aParameters[0].key,
                                 _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING),
                                 oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING));
                }
                else
                {
                    oscl_strncat(aParameters[0].key,
                                 _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING),
                                 oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING));
                }
                break;
        }
        aParameters[0].key[MP4CONFIG_KEYSTRING_SIZE-1] = 0;

        // Copy the requested info
        switch (aIndex)
        {
            case DELAY:
                if (reqattr == PVMI_KVPATTR_CUR)
                {
                    aParameters[0].value.uint32_value = iJitterBufferDurationInMs;
                }
                else if (reqattr == PVMI_KVPATTR_DEF)
                {
                    // Return default
                    aParameters[0].value.uint32_value = PVMF_MP4FFPARSER_NODE_PSEUDO_STREAMING_BUFFER_DURATION_IN_MS;
                }
                else
                {
                    // Return capability
                    range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32));
                    if (rui32 == NULL)
                    {
                        oscl_free(aParameters[0].key);
                        oscl_free(aParameters);
                        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::GetConfigParameter() "
                                                      "Memory allocation for range uint32 failed"));
                        return PVMFErrNoMemory;
                    }
                    rui32->min = MIN_JITTER_BUFFER_DURATION_IN_MS;
                    rui32->max = MAX_JITTER_BUFFER_DURATION_IN_MS;
                    aParameters[0].value.key_specific_value = (void*)rui32;
                }
                break;

            default:
                // Invalid index
                oscl_free(aParameters[0].key);
                oscl_free(aParameters);
                PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoGetPlayerParameter() Invalid index to player parameter"));
                return PVMFErrArgument;
        }
    }

    aNumParamElements = 1;
    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVPlayerEngine::DoGetPlayerParameter() Out"));
    return PVMFSuccess;

}


PVMFStatus PVMFMP4FFParserNode::VerifyAndSetConfigParameter(int index, PvmiKvp& aParameter, bool set)
{
    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::VerifyAndSetConfigParameter() In"));

    // Determine the valtype
    PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key);
    if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN)
    {
        PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::VerifyAndSetConfigParameter() "
                                      "Valtype in key string unknown"));
        return PVMFErrArgument;
    }

    if (iBaseKey == FILE_IO)
    {	// Verify the valtype
        if (keyvaltype != MP4ParserNodeConfig_FileIO_Keys[index].iValueType)
        {
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::VerifyAndSetConfigParameter() "
                                          "Valtype does not match for key"));
            return PVMFErrArgument;
        }

        switch (index)
        {
            case PV_CACHE_SIZE:
            {
                // Validate
                if (set)
                {
                    // save value locally
                    iCacheSize = aParameter.value.uint32_value;
                }
            }
            break;
            case ASYNC_READ_BUFFER_SIZE:
            {
                if (set)
                {
                    // retrieve and update
                    iAsyncReadBuffSize = aParameter.value.uint32_value;
                }
            }
            break;
            case BASEKEY_PVLOGGER_ENABLE:
            {
                if (set)
                {
                    // retrieve and update
                    iPVLoggerEnableFlag = aParameter.value.bool_value;
                }
            }
            break;
            case PVLOGGER_STATS_ENABLE:
            {
                if (set)
                {
                    // user agent update
                    iPVLoggerStateEnableFlag = aParameter.value.bool_value;
                }
            }
            break;

            case NATIVE_ACCESS_MODE:
            {
                if (set)
                {
                    iNativeAccessMode = aParameter.value.uint32_value;
                }
            }
            break;

            case FILE_HANDLE:
            {
                if (set)
                {
                }
            }
            break;

            default:
                OSCL_ASSERT(0);
        }
    }
    else if (iBaseKey == NET)
    {
        // Verify the valtype
        if (keyvaltype != MP4ParserNodeConfig_FileIO_Keys[index].iValueType)
        {
            PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::VerifyAndSetConfigParameter() "
                                          "Valtype does not match for key"));
            return PVMFErrArgument;
        }

        switch (index)
        {
            case DELAY:
            {
                // Validate
                if (set)
                {
                    // save value locally
                    iJitterBufferDurationInMs = aParameter.value.uint32_value;
                }
            }
            break;

            default:
                OSCL_ASSERT(0);
        }
    }

    PVMF_MP4FFPARSERNODE_LOGINFO((0, "PVMFMP4FFParserNode::VerifyAndSetPlayerParameter() Out"));
    return PVMFSuccess;
}
