/*
 *    Copyright (c) 2024 Project CHIP Authors
 *    All rights reserved.
 *
 *    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/TLVWriter.h"
#include <app/util/attribute-metadata.h>
#include <app/util/ember-io-storage.h>
#include <lib/core/TLVReader.h>
#include <lib/core/TLVTypes.h>
#include <lib/support/BufferReader.h>
#include <lib/support/BufferWriter.h>
#include <lib/support/Span.h>

namespace chip {
namespace app {
namespace Ember {

/// This class represents a pointer to an ember-encoded attribute in a specific memory location.
///
/// Ember attributes are stored as raw bytes for numeric types (i.e. memcpy-like storage except
/// unaligned) and strings are Pascal-like (short with 1-byte length prefix or long with 2-byte length
/// prefix).
///
/// Class is to be used as a one-shot:
///   - create it out of metadata + data span
///   - call Decode (which modifies the input data span)
class EmberAttributeDataBuffer
{
public:
#if CHIP_CONFIG_BIG_ENDIAN_TARGET
    using EndianWriter = Encoding::BigEndian::BufferWriter;
    using EndianReader = Encoding::BigEndian::Reader;
#else
    using EndianWriter = Encoding::LittleEndian::BufferWriter;
    using EndianReader = Encoding::LittleEndian::Reader;
#endif

    enum class PascalStringType
    {
        kShort,
        kLong,
    };

    static constexpr bool kIsFabricScoped = false;

    EmberAttributeDataBuffer(const EmberAfAttributeMetadata * meta, MutableByteSpan & data) :
        mIsNullable(meta->IsNullable()), mAttributeType(chip::app::Compatibility::Internal::AttributeBaseType(meta->attributeType)),
        mDataBuffer(data)
    {}

    /// Reads the data pointed into by `reader` and updates the data
    /// internally into mDataBuffer (which is then reflected outwards)
    ///
    /// Generally should be called ONLY ONCE as the internal mutable byte span gets
    /// modified by this call.
    CHIP_ERROR Decode(chip::TLV::TLVReader & reader);

    /// Writes the data encoded in the underlying buffer into the given `writer`
    ///
    /// The data in the internal data buffer is assumed to be already formatted correctly
    /// HOWEVER the size inside it will not be fully considered (i.e. encoding will use
    /// the data encoding line integer or string sizes and NOT the databuffer max size)
    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, TLV::Tag tag) const;

private:
    /// Decodes the UNSIGNED integer stored in `reader` and places its content into `writer`
    /// Takes into account internal mIsNullable.
    CHIP_ERROR DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer);

    /// Decodes the SIGNED integer stored in `reader` and places its content into `writer`
    /// Takes into account internal mIsNullable.
    CHIP_ERROR DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer);

    /// Encodes the given integer into `writer`.
    /// Takes into account internal mIsNullable.
    CHIP_ERROR EncodeInteger(chip::TLV::TLVWriter & writer, TLV::Tag tag, EndianReader & reader) const;

    /// Decodes the string/byte string contained in `reader` and stores it into `writer`.
    /// String is encoded using a pascal-prefix of size `stringType`.
    /// Takes into account internal mIsNullable.
    ///
    /// The string in `reader` is expected to be of type `tlvType`
    CHIP_ERROR DecodeAsString(chip::TLV::TLVReader & reader, PascalStringType stringType, TLV::TLVType tlvType,
                              EndianWriter & writer);

    const bool mIsNullable;                    // Contains if the attribute metadata marks the field as NULLABLE
    const EmberAfAttributeType mAttributeType; // Initialized with the attribute type from the metadata
    MutableByteSpan & mDataBuffer;             // output buffer, modified by `Decode`
};

} // namespace Ember

namespace DataModel {

/// Helper method to forward the decode of this type to the class specific implementation
inline CHIP_ERROR Decode(TLV::TLVReader & reader, Ember::EmberAttributeDataBuffer & buffer)
{
    return buffer.Decode(reader);
}

inline CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag, Ember::EmberAttributeDataBuffer & buffer)
{
    return buffer.Encode(writer, tag);
}

} // namespace DataModel
} // namespace app
} // namespace chip
