#include "bej_encoder_metadata.h"

#include "bej_common.h"
#include "bej_dictionary.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>

/**
 * @brief Maximum digits supported in the fractional part of a real number.
 */
#define BEJ_REAL_PRECISION 16

/**
 * @brief bejTupleL size of an integer.
 *
 * Maximum bytes possible for an integer is 8. Therefore to encode the length of
 * an integer using a nnint, we only need two bytes. [byte1: nnint length,
 * byte2: integer length [0-8]]
 */
#define BEJ_TUPLE_L_SIZE_FOR_BEJ_INTEGER 2

/**
 * @brief bejTupleL size of a bool.
 *
 * 1byte for the nnint length and 1 byte for the value.
 */
#define BEJ_TUPLE_L_SIZE_FOR_BEJ_BOOL 2

/**
 * @brief bejTupleF size.
 */
#define BEJ_TUPLE_F_SIZE 1

/**
 * @brief Check the name is an annotation type name.
 *
 * @param[in] name - property name.
 * @return true for annotation name, false otherwise.
 */
static bool bejIsAnnotation(const char* name)
{
    if (name == NULL)
    {
        return false;
    }
    return name[0] == '@';
}

/**
 * @brief Get the dictionary for the provided node.
 *
 * @param[in] dictionaries - available dictionaries for encoding.
 * @param[in] parentDictionary - dictionary used for the parent of this node.
 * @param[in] nodeName - name of the interested node. Can be NULL if the node
 * doesn't have a name.
 * @return a pointer to the dictionary to be used.
 */
static const uint8_t* bejGetRelatedDictionary(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    const char* nodeName)
{
    // If the node name is NULL, we have to use parent dictionary.
    if (nodeName == NULL)
    {
        return parentDictionary;
    }

    // If the parent is using annotation dictionary, that means the parent is an
    // annotation. Therefore the child (this node) should be an annotation too
    // (Could this be false?). Therefore we should use the annotation dictionary
    // for this node as well.
    if (parentDictionary == dictionaries->annotationDictionary)
    {
        return dictionaries->annotationDictionary;
    }
    return bejIsAnnotation(nodeName) ? dictionaries->annotationDictionary
                                     : dictionaries->schemaDictionary;
}

/**
 * @brief Get dictionary data for the given node.
 *
 * @param[in] dictionaries - available dictionaries.
 * @param[in] parentDictionary - the dictionary used by the provided node's
 * parent.
 * @param[in] node - node that caller is interested in.
 * @param[in] nodeIndex - index of this node within its parent.
 * @param[in] dictStartingOffset - starting dictionary child offset value of
 * this node's parent.
 * @param[out] sequenceNumber - sequence number of the node. bit0 specifies the
 * dictionary schema type: [major|annotation].
 * @param[out] nodeDictionary - if not NULL, return a pointer to the dictionary
 * used for the node.
 * @param[out] childEntryOffset - if not NULL, return the dictionary starting
 * offset used for this nodes children. If this node is not supposed to have
 * children, caller should ignore this value.
 * @return 0 if successful.
 */
static int bejFindSeqNumAndChildDictOffset(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyNode* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset, uint32_t* sequenceNumber,
    const uint8_t** nodeDictionary, uint16_t* childEntryOffset)
{
    // If the node doesn't have a name, we can't use a dictionary. So we can use
    // its parent's info.
    if (node->name == NULL || node->name[0] == '\0')
    {
        if (nodeDictionary != NULL)
        {
            *nodeDictionary = parentDictionary;
        }

        if (childEntryOffset != NULL)
        {
            *childEntryOffset = dictStartingOffset;
        }

        // If the property doesn't have a name, it has to be an element of an
        // array. In that case, sequence number is the array index.
        *sequenceNumber = (uint32_t)nodeIndex << 1;
        if (dictionaries->annotationDictionary == parentDictionary)
        {
            *sequenceNumber |= 1;
        }
        return 0;
    }

    // If we are here, the property has a name.
    const uint8_t* dictionary =
        bejGetRelatedDictionary(dictionaries, parentDictionary, node->name);
    bool isAnnotation = dictionary == dictionaries->annotationDictionary;
    // If this node's dictionary and its parent's dictionary is different,
    // this node should start searching from the beginning of its
    // dictionary. This should only happen for property annotations of form
    // property@annotation_class.annotation_name.
    if (dictionary != parentDictionary)
    {
        // Redundancy check.
        if (!isAnnotation)
        {
            fprintf(stderr,
                    "Dictionary for property %s should be the annotation "
                    "dictionary. Might be a encoding failure. Maybe the "
                    "JSON tree is not created correctly.",
                    node->name);
            return -1;
        }
        dictStartingOffset = bejDictGetFirstAnnotatedPropertyOffset();
    }

    const struct BejDictionaryProperty* property;
    int ret = bejDictGetPropertyByName(dictionary, dictStartingOffset,
                                       node->name, &property, NULL);
    if (ret != 0)
    {
        fprintf(stderr,
                "Failed to find dictionary entry for name %s. Search started "
                "at offset: %u. ret: %d\n",
                node->name, dictStartingOffset, ret);
        return ret;
    }

    if (nodeDictionary != NULL)
    {
        *nodeDictionary = dictionary;
    }

    if (childEntryOffset != NULL)
    {
        *childEntryOffset = property->childPointerOffset;
    }

    *sequenceNumber = (uint32_t)(property->sequenceNumber) << 1;
    if (isAnnotation)
    {
        *sequenceNumber |= 1;
    }
    return 0;
}

static int bejUpdateIntMetaData(const struct BejDictionaries* dictionaries,
                                const uint8_t* parentDictionary,
                                struct RedfishPropertyLeafInt* node,
                                uint16_t nodeIndex, uint16_t dictStartingOffset)
{
    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &node->leaf.nodeAttr, nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;
    // L: Length needed for the value.
    node->leaf.metaData.sflSize += BEJ_TUPLE_L_SIZE_FOR_BEJ_INTEGER;
    // V: Bytes used for the value.
    node->leaf.metaData.vSize = bejIntLengthOfValue(node->value);
    return 0;
}

static int bejUpdateStringMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafString* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset)
{
    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &(node->leaf.nodeAttr), nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;
    // L: Length needed for the string including the NULL character. Length is
    // in nnint format.
    size_t strLenWithNull = strlen(node->value) + 1;
    node->leaf.metaData.sflSize += bejNnintEncodingSizeOfUInt(strLenWithNull);
    // V: Bytes used for the value.
    node->leaf.metaData.vSize = strLenWithNull;
    return 0;
}

static int bejUpdateRealMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafReal* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset)
{
    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &(node->leaf.nodeAttr), nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    if (node->value > (double)INT64_MAX)
    {
        // TODO: We should use the exponent.
        fprintf(
            stderr,
            "Need to add support to encode double value larger than INT64_MAX\n");
        return -1;
    }

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;

    // Negative numbers greater than -1, have 0 as the bejReal whole portion.
    // Therefore to include the negative sign, we need to change the provided
    // value to a whole.fract × 10^(exp) format where |whole| > 0.
    // Eg:
    // value = -0.0000012
    // value = -1.2 x 10^(-6)
    int exp = 0;
    if ((-1 < node->value) && (node->value < 0))
    {
        // Multiply the node->value until |node->value| > 0.
        while ((-1 < node->value) && exp < BEJ_REAL_PRECISION)
        {
            node->value = node->value * 10.0;
            ++exp;
        }

        // Still if the |whole| < 0, then number is smaller than the precision
        // supported
        if (-1 < node->value)
        {
            exp = 0;
            node->value = 0;
        }

        // Exp should be negative
        exp = exp * (-1);
    }

    // We need to breakdown the real number to bejReal type to determine the
    // length. We are not gonna add an exponent. It will only be the whole part
    // and the fraction part. Get the whole part
    double originalWhole;
    double originalFract = bejModf(node->value, &originalWhole);

    // Convert the fraction to a whole value for encoding.
    // Create a new value by multiplying the original fraction by 10. Do this
    // until the fraction of the new value is 0 or we reach the precision. Eg
    // 0.00105: This fraction value has two leading zeros. We will keep
    // multiplying this by 10 until the fraction of the result of that
    // multiplication is 0.
    double originalFactConvertedToWhole = bejFabs(originalFract);
    double fract = originalFract;
    double intPart;
    uint32_t leadingZeros = 0;
    uint32_t precision = 0;
    while (fract != 0 && precision < BEJ_REAL_PRECISION)
    {
        originalFactConvertedToWhole = originalFactConvertedToWhole * 10;
        fract = bejModf(originalFactConvertedToWhole, &intPart);
        // If the integer portion is 0, that means we still have leading zeros.
        if (intPart == 0)
        {
            ++leadingZeros;
        }
        ++precision;
    }
    node->bejReal.whole = (int64_t)originalWhole;
    node->bejReal.zeroCount = leadingZeros;
    node->bejReal.fract = (int64_t)originalFactConvertedToWhole;

    // If exponent is 0, then omit the exponent.
    node->bejReal.exp = exp;
    node->bejReal.valid_exp = (exp != 0) ? true : false;

    // Calculate the sizes needed for storing bejReal fields.
    // nnint for the length of the "whole" value.
    node->leaf.metaData.vSize = BEJ_TUPLE_L_SIZE_FOR_BEJ_INTEGER;
    // Length needed for the "whole" value.
    node->leaf.metaData.vSize += bejIntLengthOfValue((int64_t)originalWhole);
    // nnint for leading zero count.
    node->leaf.metaData.vSize += bejNnintEncodingSizeOfUInt(leadingZeros);
    // nnint for the factional part.
    node->leaf.metaData.vSize +=
        bejNnintEncodingSizeOfUInt((int64_t)originalFactConvertedToWhole);
    // nnint for the exp length.
    if (node->bejReal.valid_exp)
    {
        // Length of the nnint field that represent the length of the exp.
        node->leaf.metaData.vSize += BEJ_TUPLE_L_SIZE_FOR_BEJ_INTEGER;
        node->leaf.metaData.vSize += bejIntLengthOfValue(node->bejReal.exp);
    }
    else
    {
        node->leaf.metaData.vSize += bejNnintEncodingSizeOfUInt(0);
    }

    // L: nnint for the size needed for encoding the bejReal value.
    node->leaf.metaData.sflSize +=
        bejNnintEncodingSizeOfUInt(node->leaf.metaData.vSize);
    return 0;
}

static int bejUpdateEnumMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafEnum* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset)
{
    const uint8_t* nodeDictionary;
    uint16_t childEntryOffset;
    uint32_t sequenceNumber;
    // If the enum property doesn't have a name, this will simply return the
    // nodeIndex encoded as the sequence number. If not, this will return the
    // sequence number in the dictionary and the starting dictionary index for
    // the enum values.
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &(node->leaf.nodeAttr), nodeIndex,
        dictStartingOffset, &sequenceNumber, &nodeDictionary,
        &childEntryOffset));
    // Update the sequence number of the property.
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Get the sequence number for the Enum value.
    if (node->leaf.nodeAttr.name != NULL && node->leaf.nodeAttr.name[0] != '\0')
    {
        dictStartingOffset = childEntryOffset;
    }
    const struct BejDictionaryProperty* enumValueProperty;
    int ret = bejDictGetPropertyByName(nodeDictionary, dictStartingOffset,
                                       node->value, &enumValueProperty, NULL);
    if (ret != 0)
    {
        fprintf(
            stderr,
            "Failed to find dictionary entry for enum value %s. Search started "
            "at offset: %u. ret: %d\n",
            node->value, dictStartingOffset, ret);
        return ret;
    }
    node->enumValueSeq = enumValueProperty->sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;
    // V: Bytes used for the value.
    node->leaf.metaData.vSize =
        bejNnintEncodingSizeOfUInt(enumValueProperty->sequenceNumber);
    // L: Length needed for the value nnint.
    node->leaf.metaData.sflSize +=
        bejNnintEncodingSizeOfUInt(node->leaf.metaData.vSize);
    return 0;
}

static int bejUpdateBoolMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafBool* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset)
{
    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &node->leaf.nodeAttr, nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;
    // L: Length needed for the value.
    node->leaf.metaData.sflSize += BEJ_TUPLE_L_SIZE_FOR_BEJ_BOOL;
    // V: Bytes used for the value; 0x00 or 0xFF.
    node->leaf.metaData.vSize = 1;
    return 0;
}

static int bejUpdateNullMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafNull* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset)
{
    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &node->leaf.nodeAttr, nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;
    // L: Length needed for the value. Value length for NULL type is 0. So we
    // need to encode [0x01 0x00]
    node->leaf.metaData.sflSize += BEJ_TUPLE_L_SIZE_FOR_BEJ_INTEGER;
    node->leaf.metaData.vSize = 0;
    return 0;
}

/**
 * @brief Update metadata of leaf nodes.
 *
 * @param dictionaries - dictionaries needed for encoding.
 * @param parentDictionary - dictionary used by this node's parent.
 * @param childPtr - a pointer to the leaf node.
 * @param childIndex - if this node is an array element, this is the array
 * index.
 * @param dictStartingOffset - starting dictionary child offset value of this
 * node's parent.
 * @return 0 if successful.
 */
static int bejUpdateLinkExpansionMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    struct RedfishPropertyLeafUri* node, uint16_t nodeIndex,
    uint16_t dictStartingOffset, struct BejNodeInfoCallbacks* nodeInfoCb)
{
    NULL_CHECK(nodeInfoCb, "nodeInfoCb is NULL");

    uint32_t sequenceNumber;
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &(node->leaf.nodeAttr), nodeIndex,
        dictStartingOffset, &sequenceNumber, NULL, NULL));
    node->leaf.metaData.sequenceNumber = sequenceNumber;

    // Calculate the size for encoding this in a SFLV tuple.
    // S: Size needed for encoding sequence number.
    node->leaf.metaData.sflSize = bejNnintEncodingSizeOfUInt(sequenceNumber);
    // F: Size of the format byte is 1.
    node->leaf.metaData.sflSize += BEJ_TUPLE_F_SIZE;

    // Get the payload or the URI
    if (!node->expand)
    {
        const char* uriStr = NULL;
        NULL_CHECK(nodeInfoCb->bejGetUri, "bejGetUri is NULL");
        nodeInfoCb->bejGetUri(node->resourceId, nodeInfoCb->context, &uriStr);
        if (uriStr == NULL)
        {
            fprintf(stderr, "Failed to get uri info for rid: 0x%.8x\n",
                    node->resourceId);
            return bejErrorInvalidNodeInput;
        }

        size_t strLenWithNull = strlen(uriStr) + 1;
        node->leaf.metaData.sflSize += bejNnintEncodingSizeOfUInt(strLenWithNull);
        // V: Bytes used for the value.
        node->leaf.metaData.vSize = strLenWithNull;
        return 0;
    }

    // Expand flag is present. Get the corresponding bejEncoding size.
    uint32_t encodingSize;
    NULL_CHECK(nodeInfoCb->bejGetBejEncodingSize,
               "bejGetBejEncodingSize is NULL");
    int ret = nodeInfoCb->bejGetBejEncodingSize(
        node->resourceId, nodeInfoCb->context, &encodingSize);
    if (ret != 0)
    {
        fprintf(stderr, "Failed to get bejEncoding size for rid: 0x%.8x\n",
                node->resourceId);
        return bejErrorInvalidNodeInput;
    }

    // Size of the value is payload + resource ID in nnint format.
    size_t valueLength = encodingSize + bejNnintEncodingSizeOfUInt(node->resourceId);
    // L: Length needed for the bejResourceLinkExpansion. Length is in nnint
    // format.
    node->leaf.metaData.sflSize += bejNnintEncodingSizeOfUInt(valueLength);
    // V: Bytes used for the value.
    node->leaf.metaData.vSize = valueLength;
    return 0;
}

static int bejUpdateChildMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    void* childPtr, uint16_t childIndex, uint16_t dictStartingOffset,
    struct BejNodeInfoCallbacks* nodeInfoCb)
{
    struct RedfishPropertyLeaf* chNode = childPtr;
    switch (chNode->nodeAttr.format.principalDataType)
    {
        case bejInteger:
            RETURN_IF_IERROR(
                bejUpdateIntMetaData(dictionaries, parentDictionary, childPtr,
                                     childIndex, dictStartingOffset));
            break;
        case bejString:
            RETURN_IF_IERROR(bejUpdateStringMetaData(
                dictionaries, parentDictionary, childPtr, childIndex,
                dictStartingOffset));
            break;
        case bejReal:
            RETURN_IF_IERROR(
                bejUpdateRealMetaData(dictionaries, parentDictionary, childPtr,
                                      childIndex, dictStartingOffset));
            break;
        case bejEnum:
            RETURN_IF_IERROR(
                bejUpdateEnumMetaData(dictionaries, parentDictionary, childPtr,
                                      childIndex, dictStartingOffset));
            break;
        case bejBoolean:
            RETURN_IF_IERROR(
                bejUpdateBoolMetaData(dictionaries, parentDictionary, childPtr,
                                      childIndex, dictStartingOffset));
            break;
        case bejNull:
            RETURN_IF_IERROR(
                bejUpdateNullMetaData(dictionaries, parentDictionary, childPtr,
                                      childIndex, dictStartingOffset));
            break;
        case bejResourceLinkExpansion:
            RETURN_IF_IERROR(bejUpdateLinkExpansionMetaData(
                dictionaries, parentDictionary, childPtr, childIndex,
                dictStartingOffset, nodeInfoCb));
            break;
        default:
            fprintf(stderr, "Child type %u not supported\n",
                    chNode->nodeAttr.format.principalDataType);
            return -1;
    }
    return 0;
}

/**
 * @brief Update metadata of a parent node.
 *
 * @param dictionaries - dictionaries needed for encoding.
 * @param parentDictionary - dictionary used by this node's parent.
 * @param dictStartingOffset - starting dictionary child offset value of this
 * node's parent.
 * @param node - a pointer to the parent node.
 * @param nodeIndex - If this node is an array element, this is the array index.
 * @return 0 if successful.
 */
static int bejUpdateParentMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    uint16_t dictStartingOffset, struct RedfishPropertyParent* node,
    uint16_t nodeIndex)
{
    const uint8_t* nodeDictionary;
    uint16_t childEntryOffset;
    uint32_t sequenceNumber;
    // Get the dictionary related data from the node.
    RETURN_IF_IERROR(bejFindSeqNumAndChildDictOffset(
        dictionaries, parentDictionary, &node->nodeAttr, nodeIndex,
        dictStartingOffset, &sequenceNumber, &nodeDictionary,
        &childEntryOffset));

    node->metaData.sequenceNumber = sequenceNumber;
    node->metaData.childrenDictPropOffset = childEntryOffset;
    node->metaData.nextChild = node->firstChild;
    node->metaData.nextChildIndex = 0;
    node->metaData.dictionary = nodeDictionary;
    node->metaData.vSize = 0;

    // S: Size needed for encoding sequence number.
    node->metaData.sflSize =
        bejNnintEncodingSizeOfUInt(node->metaData.sequenceNumber);
    // F: Size of the format byte is 1.
    node->metaData.sflSize += 1;
    // V: Only for bejArray and bejSet types, value size should include the
    // children count. We need to add the size needs to encode all the children
    // later.
    if (node->nodeAttr.format.principalDataType != bejPropertyAnnotation)
    {
        node->metaData.vSize = bejNnintEncodingSizeOfUInt(node->nChildren);
    }
    return 0;
}

/**
 * @brief Update metadata of child nodes.
 *
 * If a child node contains its own child nodes, it will be added to the stack
 * and function will return.
 *
 * @param dictionaries - dictionaries needed for encoding.
 * @param parent - parent node.
 * @param stack - stack holding parent nodes.
 * @return 0 if successful.
 */
static int bejProcessChildNodes(const struct BejDictionaries* dictionaries,
                                struct RedfishPropertyParent* parent,
                                struct BejPointerStackCallback* stack,
                                struct BejNodeInfoCallbacks* nodeInfoCb)
{
    // Get the next child of the parent.
    void* childPtr = parent->metaData.nextChild;

    // Process all the children belongs to the parent.
    while (childPtr != NULL)
    {
        // If we find a child with its own child nodes, add it to the stack and
        // return.
        if (bejTreeIsParentType(childPtr))
        {
            RETURN_IF_IERROR(bejUpdateParentMetaData(
                dictionaries, parent->metaData.dictionary,
                parent->metaData.childrenDictPropOffset, childPtr,
                parent->metaData.nextChildIndex));

            RETURN_IF_IERROR(stack->stackPush(childPtr, stack->stackContext));
            bejParentGoToNextChild(parent, childPtr);
            return 0;
        }

        RETURN_IF_IERROR(bejUpdateChildMetaData(
            dictionaries, parent->metaData.dictionary, childPtr,
            parent->metaData.nextChildIndex,
            parent->metaData.childrenDictPropOffset, nodeInfoCb));
        // Use the child value size to update the parent value size.
        struct RedfishPropertyLeaf* leafChild = childPtr;
        // V: Include the child size in parent's value size.
        parent->metaData.vSize +=
            (leafChild->metaData.sflSize + leafChild->metaData.vSize);

        // Get the next child belongs to the parent.
        childPtr = bejParentGoToNextChild(parent, childPtr);
    }
    return 0;
}

int bejUpdateNodeMetadata(const struct BejDictionaries* dictionaries,
                          uint16_t majorSchemaStartingOffset,
                          struct RedfishPropertyParent* root,
                          struct BejPointerStackCallback* stack,
                          struct BejNodeInfoCallbacks* nodeInfoCb)
{
    // Decide the starting property offset of the dictionary.
    uint16_t dictOffset = bejDictGetPropertyHeadOffset();
    if (majorSchemaStartingOffset != BEJ_DICTIONARY_START_AT_HEAD)
    {
        dictOffset = majorSchemaStartingOffset;
    }

    // Initialize root node metadata.
    RETURN_IF_IERROR(
        bejUpdateParentMetaData(dictionaries, dictionaries->schemaDictionary,
                                dictOffset, root, /*childIndex=*/0));

    // Push the root to the stack. Because we are not done with the parent node
    // yet. Need to figure out all bytes need to encode children of this parent,
    // and save it in the parent metadata.
    RETURN_IF_IERROR(stack->stackPush(root, stack->stackContext));

    while (!stack->stackEmpty(stack->stackContext))
    {
        // Get the parent at the top of the stack. Stack is only popped if the
        // parent stack entry has no pending children; That is
        // parent->metaData.nextChild == NULL.
        struct RedfishPropertyParent* parent =
            stack->stackPeek(stack->stackContext);

        // Calculate metadata of all the child nodes of the current parent node.
        // If one of these child nodes has its own child nodes, that child node
        // will be added to the stack and this function will return.
        RETURN_IF_IERROR(bejProcessChildNodes(dictionaries, parent, stack, nodeInfoCb));

        // If a new node hasn't been added to the stack, we know that this
        // parent's child nodes have been processed. If not, do not pop the
        // stack.
        if (parent != stack->stackPeek(stack->stackContext))
        {
            continue;
        }

        // If we are here;
        // Then "parent" is the top element of the stack.
        // All the children of "parent" has been processed.

        // Remove the "parent" from the stack.
        parent = stack->stackPop(stack->stackContext);
        // L: Add the length needed to store the number of bytes used for the
        // parent's value.
        parent->metaData.sflSize +=
            bejNnintEncodingSizeOfUInt(parent->metaData.vSize);

        // Since we now know the total size needs to encode the node pointed by
        // "parent" variable, we should add that to the value size of this
        // node's parent. Since we already popped this node from the stack, top
        // of the stack element is this nodes's parent. "parentsParent" can be
        // NULL if the node pointed by "parent" variable is the root.
        struct RedfishPropertyParent* parentsParent =
            stack->stackPeek(stack->stackContext);
        if (parentsParent != NULL)
        {
            // V: Include the total size to encode the current parent in its
            // parent's value size.
            parentsParent->metaData.vSize +=
                (parent->metaData.sflSize + parent->metaData.vSize);
        }
    }
    return 0;
}
