/*
 *    Copyright (c) 2022 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 "app/persistence/AttributePersistenceProvider.h"
#include <app/persistence/DeferredAttributePersistenceProvider.h>

#include <platform/CHIPDeviceLayer.h>

namespace chip {
namespace app {

CHIP_ERROR DeferredAttribute::PrepareWrite(System::Clock::Timestamp flushTime, const ByteSpan & value)
{
    mFlushTime = flushTime;

    if (mValue.AllocatedSize() != value.size())
    {
        mValue.Alloc(value.size());
        VerifyOrReturnError(mValue, CHIP_ERROR_NO_MEMORY);
    }

    memcpy(mValue.Get(), value.data(), value.size());
    return CHIP_NO_ERROR;
}

void DeferredAttribute::Flush(AttributePersistenceProvider & persister)
{
    VerifyOrReturn(IsArmed());
    TEMPORARY_RETURN_IGNORED persister.WriteValue(mPath, ByteSpan(mValue.Get(), mValue.AllocatedSize()));
    mValue.Free();
}

CHIP_ERROR DeferredAttributePersistenceProvider::WriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue)
{
    for (DeferredAttribute & da : mDeferredAttributes)
    {
        if (da.Matches(aPath))
        {
            ReturnErrorOnFailure(da.PrepareWrite(System::SystemClock().GetMonotonicTimestamp() + mWriteDelay, aValue));
            FlushAndScheduleNext();
            return CHIP_NO_ERROR;
        }
    }

    return mPersister.WriteValue(aPath, aValue);
}

CHIP_ERROR DeferredAttributePersistenceProvider::ReadValue(const ConcreteAttributePath & aPath, MutableByteSpan & aValue)
{
    return mPersister.ReadValue(aPath, aValue);
}

void DeferredAttributePersistenceProvider::FlushAndScheduleNext()
{
    const System::Clock::Timestamp now     = System::SystemClock().GetMonotonicTimestamp();
    System::Clock::Timestamp nextFlushTime = System::Clock::Timestamp::max();

    for (DeferredAttribute & da : mDeferredAttributes)
    {
        if (!da.IsArmed())
        {
            continue;
        }

        if (da.GetFlushTime() <= now)
        {
            da.Flush(mPersister);
        }
        else
        {
            nextFlushTime = std::min(nextFlushTime, da.GetFlushTime());
        }
    }

    if (nextFlushTime != System::Clock::Timestamp::max())
    {
        TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().StartTimer(
            nextFlushTime - now,
            [](System::Layer *, void * me) { static_cast<DeferredAttributePersistenceProvider *>(me)->FlushAndScheduleNext(); },
            this);
    }
}

} // namespace app
} // namespace chip
