/*
 INTEL CONFIDENTIAL
 Copyright 2009 Intel Corporation All Rights Reserved.
 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.

 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
 */

//#include <glib.h>

#include "vbp_loader.h"
#include "vbp_utils.h"

/**
 *
 */
uint32 vbp_open(uint32 parser_type, Handle *hcontext)
{
    vbp_context **ppcontext;
    uint32 error;

    if (NULL == hcontext)
    {
        return VBP_PARM;
    }

    *hcontext = NULL;  /* prepare for failure. */

    ppcontext = (vbp_context **)hcontext;

    /**
    * TO DO:
    * check if vbp context has been created.
    */

    error = vbp_utils_create_context(parser_type, ppcontext);
    if (VBP_OK != error)
    {
        ETRACE("Failed to create context: %d.", error);
    }

    return error;
}

/**
 *
 */
uint32 vbp_close(Handle hcontext)
{
    uint32 error;

    if (NULL == hcontext)
    {
        return VBP_PARM;
    }

    vbp_context *pcontext = (vbp_context *)hcontext;

    if (MAGIC_NUMBER != pcontext->identifier)
    {
        /* not a valid vbp context. */
        ETRACE("context is not initialized");
        return VBP_INIT;
    }
    error = vbp_utils_destroy_context(pcontext);
    if (VBP_OK != error)
    {
        ETRACE("Failed to destroy context: %d.", error);
    }

    return error;
}


/**
 *
 */
uint32 vbp_parse(Handle hcontext, uint8 *data, uint32 size, uint8 init_data_flag)
{
    vbp_context *pcontext;
    uint32 error = VBP_OK;

    if ((NULL == hcontext) || (NULL == data) || (0 == size))
    {
        ETRACE("Invalid input parameters.");
        return VBP_PARM;
    }

    pcontext = (vbp_context *)hcontext;

    if (MAGIC_NUMBER != pcontext->identifier)
    {
        ETRACE("context is not initialized");
        return VBP_INIT;
    }

    error = vbp_utils_parse_buffer(pcontext, data, size, init_data_flag);

    if (VBP_OK != error)
    {
        ETRACE("Failed to parse buffer: %d.", error);
    }
    return error;
}

/**
 *
 */
uint32 vbp_query(Handle hcontext, void **data)
{
    vbp_context *pcontext;
    uint32 error = VBP_OK;

    if ((NULL == hcontext) || (NULL == data))
    {
        ETRACE("Invalid input parameters.");
        return VBP_PARM;
    }

    pcontext = (vbp_context *)hcontext;

    if (MAGIC_NUMBER != pcontext->identifier)
    {
        ETRACE("context is not initialized");
        return VBP_INIT;
    }

    error = vbp_utils_query(pcontext, data);

    if (VBP_OK != error)
    {
        ETRACE("Failed to query parsing result: %d.", error);
    }
    return error;
}

/**
 *
 */
uint32 vbp_flush(Handle hcontext)
{
    vbp_context *pcontext;
    uint32 error = VBP_OK;

    if (NULL == hcontext)
    {
        ETRACE("Invalid input parameters.");
        return VBP_PARM;
    }

    pcontext = (vbp_context *)hcontext;

    if (MAGIC_NUMBER != pcontext->identifier)
    {
        ETRACE("context is not initialized");
        return VBP_INIT;
    }

    error = vbp_utils_flush(pcontext);

    return error;
}
