/*
 *    Copyright (c) 2026 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/AttributePersistenceMigration.h>
#include <lib/support/logging/CHIPLogging.h>

namespace chip::app {

CHIP_ERROR MigrateFromSafeToAttributePersistenceProvider(SafeAttributePersistenceProvider & safeProvider,
                                                         AttributePersistenceProvider & dstProvider,
                                                         const ConcreteClusterPath & cluster,
                                                         Span<const AttrMigrationData> attributes, MutableByteSpan buffer)
{
    bool hadMigrationErrors = false;
    ConcreteAttributePath attrPath;

    for (const auto & entry : attributes)
    {
        attrPath = ConcreteAttributePath(cluster.mEndpointId, cluster.mClusterId, entry.attributeId);

        // Create a copy of the buffer to check if the value is already in the AttributePersistence.
        // If the attribute value is already stored in AttributePersistence, skip it.
        // Note: we assume any other error (e.g. including buffer too small) to be an indication that
        //       the key exists. The only case we migrate is if we are explicitly told "not found".
        MutableByteSpan readAttrBuffer = buffer;
        if (dstProvider.ReadValue(attrPath, readAttrBuffer) != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
        {
            continue;
        }

        // Verify that the migrator provided is not null.
        if (entry.migrator == nullptr)
        {
            hadMigrationErrors = true;
            ChipLogError(DataManagement,
                         "AttributeMigration: Null migrator for attribute '" ChipLogFormatMEI "' from cluster '" ChipLogFormatMEI
                         "'",
                         ChipLogValueMEI(entry.attributeId), ChipLogValueMEI(cluster.mClusterId));
            continue;
        }

        // We make a copy of the buffer so it can be resized
        // Still refers to same internal buffer though
        // Read value from the safe provider, will resize copyOfBuffer to read size
        MutableByteSpan copyOfBuffer = buffer;
        // If there was an error reading from SafeAttributePersistence, then we shouldn't try to write that value
        // to AttributePersistence
        ChipError attributeMigrationError = entry.migrator(attrPath, safeProvider, copyOfBuffer);
        if (attributeMigrationError != CHIP_NO_ERROR)
        {
            // If the value was not found in SafeAttributePersistence, it means that it was already migrated or that
            // there wasn't a value stored for this attribute in the first place, so we skip it.
            if (attributeMigrationError != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
            {
                hadMigrationErrors = true;
                ChipLogError(DataManagement,
                             "AttributeMigration: Error reading SafeAttribute '" ChipLogFormatMEI
                             "' from cluster '" ChipLogFormatMEI "' (err=%" CHIP_ERROR_FORMAT ")",
                             ChipLogValueMEI(entry.attributeId), ChipLogValueMEI(cluster.mClusterId),
                             attributeMigrationError.Format());
            }
            continue;
        }

        // Delete from the safe provider immediately after a successful read, so we only try to
        // migrate the persisted values once and avoid re-migrating after a reset.
        attributeMigrationError = safeProvider.SafeDeleteValue(attrPath);
        if (attributeMigrationError != CHIP_NO_ERROR)
        {
            hadMigrationErrors = true;
            ChipLogError(DataManagement,
                         "AttributeMigration: Error deleting SafeAttribute '" ChipLogFormatMEI "' from cluster '" ChipLogFormatMEI
                         "' (err=%" CHIP_ERROR_FORMAT ")",
                         ChipLogValueMEI(entry.attributeId), ChipLogValueMEI(cluster.mClusterId), attributeMigrationError.Format());
        }

        // Write value from SafeAttributePersistence into AttributePersistence
        attributeMigrationError = dstProvider.WriteValue(attrPath, copyOfBuffer);
        if (attributeMigrationError != CHIP_NO_ERROR)
        {
            hadMigrationErrors = true;
            ChipLogError(DataManagement,
                         "AttributeMigration: Error writing Attribute '" ChipLogFormatMEI "' from cluster '" ChipLogFormatMEI
                         "' (err=%" CHIP_ERROR_FORMAT ")",
                         ChipLogValueMEI(entry.attributeId), ChipLogValueMEI(cluster.mClusterId), attributeMigrationError.Format());
        }
    }
    return hadMigrationErrors ? CHIP_ERROR_HAD_FAILURES : CHIP_NO_ERROR;
}

namespace DefaultMigrators {
CHIP_ERROR SafeValue(const ConcreteAttributePath & attrPath, SafeAttributePersistenceProvider & provider, MutableByteSpan & buffer)
{
    return provider.SafeReadValue(attrPath, buffer);
}
} // namespace DefaultMigrators
} // namespace chip::app
