/*
 *    Copyright (c) 2021-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.
 */
#include <app/AttributeValueEncoder.h>

namespace chip {
namespace app {

namespace {

constexpr uint32_t kEndOfListByteCount = 1;
// 2 bytes: one to end the AttributeDataIB and one to end the AttributeReportIB.
constexpr uint32_t kEndOfAttributeReportIBByteCount = 2;
constexpr TLV::TLVType kAttributeDataIBType         = TLV::kTLVType_Structure;

} // anonymous namespace

CHIP_ERROR AttributeValueEncoder::EnsureListStarted()
{
    VerifyOrDie(mCurrentEncodingListIndex == kInvalidListIndex);

    mEncodingInitialList = (mEncodeState.mCurrentEncodingListIndex == kInvalidListIndex);
    if (mEncodingInitialList)
    {
        // Clear mAllowPartialData flag here since this encode procedure is not atomic.
        // The most common error in this function is CHIP_ERROR_NO_MEMORY / CHIP_ERROR_BUFFER_TOO_SMALL, just revert and try
        // next time is ok.
        mEncodeState.mAllowPartialData = false;

        AttributeReportBuilder builder;

        mPath.mListOp = ConcreteDataAttributePath::ListOperation::ReplaceAll;
        ReturnErrorOnFailure(builder.PrepareAttribute(mAttributeReportIBsBuilder, mPath, mDataVersion));

        auto * attributeDataWriter = mAttributeReportIBsBuilder.GetAttributeReport().GetAttributeData().GetWriter();
        TLV::TLVType outerType;
        ReturnErrorOnFailure(
            attributeDataWriter->StartContainer(TLV::ContextTag(AttributeDataIB::Tag::kData), TLV::kTLVType_Array, outerType));
        VerifyOrDie(outerType == kAttributeDataIBType);

        // Instead of reserving hardcoded amounts, we could checkpoint the
        // writer, encode array end and FinishAttribute, check that this fits,
        // measure how much the writer advanced, then restore the checkpoint,
        // reserve the measured value, and save it.  But that's probably more
        // cycles than just reserving this known constant.
        ReturnErrorOnFailure(
            mAttributeReportIBsBuilder.GetWriter()->ReserveBuffer(kEndOfAttributeReportIBByteCount + kEndOfListByteCount));

        mEncodeState.mCurrentEncodingListIndex = 0;
    }
    else
    {
        // For all elements in the list, a report with append operation will be generated. This will not be changed during encoding
        // of each report since the users cannot access mPath.
        mPath.mListOp = ConcreteDataAttributePath::ListOperation::AppendItem;
    }

    mCurrentEncodingListIndex = 0;

    // After encoding the initial list start, the remaining items are atomically encoded into the buffer. Tell report engine to not
    // revert partial data.
    mEncodeState.mAllowPartialData = true;

    return CHIP_NO_ERROR;
}

void AttributeValueEncoder::EnsureListEnded()
{
    if (!mEncodingInitialList)
    {
        // Nothing to do.
        return;
    }

    // Unreserve the space we reserved just for this.  Crash if anything here
    // fails, because that would mean that we've corrupted our data, and since
    // mEncodeState.mAllowPartialData is true nothing will clean up for us here.
    auto * attributeDataWriter = mAttributeReportIBsBuilder.GetAttributeReport().GetAttributeData().GetWriter();
    VerifyOrDie(attributeDataWriter->UnreserveBuffer(kEndOfListByteCount + kEndOfAttributeReportIBByteCount) == CHIP_NO_ERROR);
    VerifyOrDie(attributeDataWriter->EndContainer(kAttributeDataIBType) == CHIP_NO_ERROR);

    AttributeReportBuilder builder;
    VerifyOrDie(builder.FinishAttribute(mAttributeReportIBsBuilder) == CHIP_NO_ERROR);

    if (!mEncodedAtLeastOneListItem)
    {
        // If we have not managed to encode any list items, we don't actually
        // want to output the single "empty list" IB that will then be followed
        // by one-IB-per-item in the next packet.  Just have the reporting
        // engine roll back our entire attribute and put us in the next packet.
        //
        // If we succeeded at encoding the whole list (i.e. the list is in fact
        // empty and we fit in the packet), mAllowPartialData will be ignored,
        // so it's safe to set it to false even if encoding succeeded.
        mEncodeState.mAllowPartialData = false;
    }
}

} // namespace app
} // namespace chip
