#include "bej_dictionary.h"

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

/**
 * @brief Get the index for a property offset. First property will be at index
 * 0.
 *
 * @param[in] propertyOffset - a valid property offset.
 * @return index of the property.
 */
static uint16_t bejGetPropertyEntryIndex(uint16_t propertyOffset)
{
    return (propertyOffset - bejDictGetPropertyHeadOffset()) /
           sizeof(struct BejDictionaryProperty);
}

/**
 * @brief  Validate a property offset.
 *
 * @param[in] dictionary - pointer to the dictionary.
 * @param[in] propertyOffset - offset needed to be validated.
 * @return true if propertyOffset is a valid offset.
 */
static bool bejValidatePropertyOffset(const uint8_t* dictionary,
                                      uint16_t propertyOffset)
{
    // propertyOffset should be greater than or equal to first property offset.
    if (propertyOffset < bejDictGetPropertyHeadOffset())
    {
        fprintf(
            stderr,
            "Invalid property offset. Pointing to Dictionary header data\n");
        return false;
    }

    // propertyOffset should be a multiple of sizeof(BejDictionaryProperty)
    // starting from first property within the dictionary.
    if ((propertyOffset - bejDictGetPropertyHeadOffset()) %
        sizeof(struct BejDictionaryProperty))
    {
        fprintf(stderr, "Invalid property offset. Does not point to beginning "
                        "of property\n");
        return false;
    }

    const struct BejDictionaryHeader* header =
        (const struct BejDictionaryHeader*)dictionary;
    uint16_t propertyIndex = bejGetPropertyEntryIndex(propertyOffset);
    if (propertyIndex >= header->entryCount)
    {
        fprintf(stderr,
                "Invalid property offset %u. It falls outside of dictionary "
                "properties\n",
                propertyOffset);
        return false;
    }

    return true;
}

uint16_t bejDictGetPropertyHeadOffset(void)
{
    // First property is present soon after the dictionary header.
    return sizeof(struct BejDictionaryHeader);
}

uint16_t bejDictGetFirstAnnotatedPropertyOffset(void)
{
    // The first property available is the "Annotations" set which is the parent
    // for all properties. Next immediate property is the first property we
    // need.
    return sizeof(struct BejDictionaryHeader) +
           sizeof(struct BejDictionaryProperty);
}

int bejDictGetProperty(const uint8_t* dictionary,
                       uint16_t startingPropertyOffset, uint16_t sequenceNumber,
                       const struct BejDictionaryProperty** property)
{
    uint16_t propertyOffset = startingPropertyOffset;
    const struct BejDictionaryHeader* header =
        (const struct BejDictionaryHeader*)dictionary;

    if (!bejValidatePropertyOffset(dictionary, propertyOffset))
    {
        return bejErrorInvalidPropertyOffset;
    }
    uint16_t propertyIndex = bejGetPropertyEntryIndex(propertyOffset);

    for (uint16_t index = propertyIndex; index < header->entryCount; ++index)
    {
        const struct BejDictionaryProperty* p =
            (const struct BejDictionaryProperty*)(dictionary + propertyOffset);
        if (p->sequenceNumber == sequenceNumber)
        {
            *property = p;
            return 0;
        }
        propertyOffset += sizeof(struct BejDictionaryProperty);
    }
    return bejErrorUnknownProperty;
}

const char* bejDictGetPropertyName(const uint8_t* dictionary,
                                   uint16_t nameOffset, uint8_t nameLength)
{
    if (nameLength == 0)
    {
        return "";
    }
    return (const char*)(dictionary + nameOffset);
}

int bejDictGetPropertyByName(
    const uint8_t* dictionary, uint16_t startingPropertyOffset,
    const char* propertyName, const struct BejDictionaryProperty** property,
    uint16_t* propertyOffset)
{
    NULL_CHECK(property, "property in bejDictGetPropertyByName");

    uint16_t curPropertyOffset = startingPropertyOffset;
    const struct BejDictionaryHeader* header =
        (const struct BejDictionaryHeader*)dictionary;

    if (!bejValidatePropertyOffset(dictionary, curPropertyOffset))
    {
        return bejErrorInvalidPropertyOffset;
    }
    uint16_t propertyIndex = bejGetPropertyEntryIndex(curPropertyOffset);

    for (uint16_t index = propertyIndex; index < header->entryCount; ++index)
    {
        const struct BejDictionaryProperty* p =
            (const struct BejDictionaryProperty*)(dictionary +
                                                  curPropertyOffset);
        if (strcmp(propertyName,
                   bejDictGetPropertyName(dictionary, p->nameOffset,
                                          p->nameLength)) == 0)
        {
            *property = p;
            // propertyOffset is an optional output.
            if (propertyOffset != NULL)
            {
                *propertyOffset = curPropertyOffset;
            }
            return 0;
        }
        curPropertyOffset += sizeof(struct BejDictionaryProperty);
    }
    return bejErrorUnknownProperty;
}
