/*
 *
 *    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.
 */
#pragma once

#include <lib/core/CHIPEncoding.h>
#include <lib/core/Optional.h>
#include <lib/dnssd/minimal_mdns/core/QName.h>
#include <lib/support/BufferWriter.h>

namespace mdns {
namespace Minimal {

/**
 * Handles writing into mdns packets.
 *
 * Generally the same as a binary data writer, but can handle qname writing with
 * compression.
 */
class RecordWriter
{
public:
    RecordWriter(chip::Encoding::BigEndian::BufferWriter * output) : mOutput(output) { Reset(); }

    void Reset()
    {
        for (size_t i = 0; i < kMaxCachedReferences; i++)
        {
            mPreviousQNames[i] = kInvalidOffset;
        }
    }

    chip::Encoding::BigEndian::BufferWriter & Writer() { return *mOutput; }

    /// Writes  the given qname into the underlying buffer, applying
    /// compression if possible
    RecordWriter & WriteQName(const FullQName & qname);

    /// Writes  the given qname into the underlying buffer, applying
    /// compression if possible
    RecordWriter & WriteQName(const SerializedQNameIterator & qname);

    inline RecordWriter & Put8(uint8_t value)
    {
        mOutput->Put8(value);
        return *this;
    }

    inline RecordWriter & Put16(uint16_t value)
    {
        mOutput->Put16(value);
        return *this;
    }

    inline RecordWriter & Put32(uint32_t value)
    {
        mOutput->Put32(value);
        return *this;
    }

    inline RecordWriter & PutString(const char * value)
    {
        mOutput->Put(value);
        return *this;
    }

    inline RecordWriter & Put(const BytesRange & range)
    {
        mOutput->Put(range.Start(), range.Size());
        return *this;
    }

    inline bool Fit() const { return mOutput->Fit(); }

private:
    // How  many paths to remember as 'previously written'
    // and make use of them
    static constexpr size_t kMaxCachedReferences = 8;
    static constexpr uint16_t kInvalidOffset     = 0xFFFF;
    static constexpr uint16_t kMaxReuseOffset    = 0x3FFF;

    // Where the data is being outputted
    chip::Encoding::BigEndian::BufferWriter * mOutput;
    uint16_t mPreviousQNames[kMaxCachedReferences];

    /// Find the offset at which this qname was previously seen (if any)
    /// works with QName and SerializedQNameIterator
    template <class T>
    chip::Optional<uint16_t> FindPreviousName(const T & name) const
    {
        for (size_t i = 0; i < kMaxCachedReferences; i++)
        {
            SerializedQNameIterator previous = PreviousName(i);

            // Any of the sub-segments may match
            while (previous.IsValid())
            {
                if (previous == name)
                {
                    return chip::Optional<uint16_t>::Value(previous.OffsetInCurrentValidData());
                }

                if (!previous.Next())
                {
                    break;
                }
            }
        }

        return chip::Optional<uint16_t>::Missing();
    }

    /// Gets the iterator corresponding to the previous name
    /// with the given index.
    ///
    /// Will return an iterator  that is not valid if
    /// lookbehind index is not valid
    SerializedQNameIterator PreviousName(size_t index) const;

    /// Keep track that a qname was written at the given offset
    void RememberWrittenQnameOffset(size_t offset);
};

} // namespace Minimal
} // namespace mdns
