/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    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.
 */
#include <assert.h>
#include <strings.h>

#include "QName.h"

namespace mdns {
namespace Minimal {

bool SerializedQNameIterator::Next()
{
    return mIsValid && Next(true);
}

bool SerializedQNameIterator::Next(bool followIndirectPointers)
{
    if (!mIsValid)
    {
        return false;
    }

    while (true)
    {
        assert(mValidData.Contains(mCurrentPosition));

        const uint8_t length = *mCurrentPosition;
        if (*mCurrentPosition == 0)
        {
            // Done with all items
            return false;
        }

        if ((length & kPtrMask) == kPtrMask)
        {
            if (!followIndirectPointers)
            {
                // Stop at first indirect pointer
                return false;
            }

            // PTR contains 2 bytes
            if (!mValidData.Contains(mCurrentPosition + 1))
            {
                mIsValid = false;
                return false;
            }

            size_t offset = ((*mCurrentPosition & 0x3F) << 8) | *(mCurrentPosition + 1);
            if (offset > mLookBehindMax)
            {
                // Potential infinite recursion.
                mIsValid = false;
                return false;
            }
            if (offset > mValidData.Size())
            {
                // offset too large
                mIsValid = false;
                return false;
            }

            // Look behind has to keep going backwards, otherwise we may
            // get into an infinite list
            if (offset >= static_cast<size_t>(mCurrentPosition - mValidData.Start()))
            {
                mIsValid = false;
                return false;
            }

            mLookBehindMax   = offset;
            mCurrentPosition = mValidData.Start() + offset;
        }
        else
        {
            // This branch handles non-pointer data. This will be string of size [length].
            if (length > kMaxValueSize)
            {
                // value is too large (larger than RFC limit)
                mIsValid = false;
                return false;
            }

            if (!mValidData.Contains(mCurrentPosition + 1 + length))
            {
                // string outside valid data
                mIsValid = false;
                return false;
            }

            memcpy(mValue, mCurrentPosition + 1, length);
            mValue[length]   = '\0';
            mCurrentPosition = mCurrentPosition + length + 1;
            return true;
        }
    }
}

const uint8_t * SerializedQNameIterator::FindDataEnd()
{
    while (Next(false))
    {
        // nothing to do, just advance
    }

    if (!IsValid())
    {
        return nullptr;
    }

    // normal end
    if (*mCurrentPosition == 0)
    {
        // mCurrentPosition MUST already be valid
        return mCurrentPosition + 1;
    }

    // ends with a dataptr
    if ((*mCurrentPosition & kPtrMask) == kPtrMask)
    {
        if (!mValidData.Contains(mCurrentPosition + 1))
        {
            return nullptr;
        }
        return mCurrentPosition + 2;
    }

    // invalid data
    return nullptr;
}

bool SerializedQNameIterator::operator==(const FullQName & other) const
{
    SerializedQNameIterator self = *this; // allow iteration
    size_t idx                   = 0;

    while ((idx < other.nameCount) && self.Next())
    {
        if (strcasecmp(self.Value(), other.names[idx]) != 0)
        {
            return false;
        }
        idx++;
    }

    return ((idx == other.nameCount) && !self.Next());
}

bool SerializedQNameIterator::operator==(const SerializedQNameIterator & other) const
{
    SerializedQNameIterator a = *this; // allow iteration
    SerializedQNameIterator b = other;

    while (true)
    {
        bool hasA = a.Next();
        bool hasB = b.Next();

        if (hasA ^ hasB)
        {
            return false; /// one is longer than the other
        }

        if (!a.IsValid() || !b.IsValid())
        {
            return false; // invalid data
        }

        if (!hasA || !hasB)
        {
            break;
        }

        if (strcasecmp(a.Value(), b.Value()) != 0)
        {
            return false;
        }
    }

    return a.IsValid() && b.IsValid();
}

bool FullQName::operator==(const FullQName & other) const
{
    if (nameCount != other.nameCount)
    {
        return false;
    }
    for (size_t i = 0; i < nameCount; i++)
    {
        if (strcasecmp(names[i], other.names[i]) != 0)
        {
            return false;
        }
    }
    return true;
}

} // namespace Minimal
} // namespace mdns
