#include "bej_encoder_metadata.h"

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

#include <math.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) && isAnnotation && (dictionary == parentDictionary))
    {
        dictStartingOffset = bejDictGetFirstAnnotatedPropertyOffset();
        ret = bejDictGetPropertyByName(dictionary, dictStartingOffset,
                                       node->name, &property, NULL);
        bejTreeUpdateNodeFlags(node, false, true, false);
    }
    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;
    // 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 = modf(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 = fabs(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 = modf(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;
    // We are omitting exp. So the exp length should be 0.
    node->bejReal.expLen = 0;
    node->bejReal.exp = 0;

    // 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. We are omitting exp. So the exp length should
    // be 0.
    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 bejUpdateLeafNodeMetaData(
    const struct BejDictionaries* dictionaries, const uint8_t* parentDictionary,
    void* childPtr, uint16_t childIndex, uint16_t dictStartingOffset)
{
    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;
        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)
{
    // 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(bejUpdateLeafNodeMetaData(
            dictionaries, parent->metaData.dictionary, childPtr,
            parent->metaData.nextChildIndex,
            parent->metaData.childrenDictPropOffset));
        // 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)
{
    // 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));

        // 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;
}
