/**
 *
 *    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.
 */

#include "scenes.h"
#include "app/util/common.h"
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/command-id.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/util/af.h>

#ifdef EMBER_AF_PLUGIN_GROUPS_SERVER
#include <app/clusters/groups-server/groups-server.h>
#endif

#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
#include "../zll-scenes-server/zll-scenes-server.h"
#endif

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::Scenes;

uint8_t emberAfPluginScenesServerEntriesInUse = 0;
#if !defined(EMBER_AF_PLUGIN_SCENES_USE_TOKENS) || defined(EZSP_HOST)
EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[MATTER_SCENES_TABLE_SIZE];
#endif

static bool readServerAttribute(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, const char * name,
                                uint8_t * data, uint8_t size)
{
    bool success = false;
    if (emberAfContainsServer(endpoint, clusterId))
    {
        EmberAfStatus status = emberAfReadServerAttribute(endpoint, clusterId, attributeId, data, size);
        if (status == EMBER_ZCL_STATUS_SUCCESS)
        {
            success = true;
        }
        else
        {
            emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "read", name, status);
        }
    }
    return success;
}

static EmberAfStatus writeServerAttribute(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, const char * name,
                                          uint8_t * data, EmberAfAttributeType type)
{
    EmberAfStatus status = emberAfWriteServerAttribute(endpoint, clusterId, attributeId, data, type);
    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status);
    }
    return status;
}

bool isEndpointInGroup(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId)
{
#ifdef EMBER_AF_PLUGIN_GROUPS_SERVER
    return (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID ||
            emberAfGroupsClusterEndpointInGroupCallback(fabricIndex, endpoint, groupId));
#else
    return (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID);
#endif // EMBER_AF_PLUGIN_GROUPS_SERVER
}

void emberAfScenesClusterServerInitCallback(EndpointId endpoint)
{
#if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
    {
        // The high bit of Name Support indicates whether scene names are supported.
        uint8_t nameSupport = EMBER_BIT(7);
        writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID, "name support", (uint8_t *) &nameSupport,
                             ZCL_BITMAP8_ATTRIBUTE_TYPE);
    }
#endif
#if !defined(EMBER_AF_PLUGIN_SCENES_USE_TOKENS) || defined(EZSP_HOST)
    {
        uint8_t i;
        for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
        {
            EmberAfSceneTableEntry entry;
            emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
            entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
            emberAfPluginScenesServerSaveSceneEntry(entry, i);
        }
        emberAfPluginScenesServerSetNumSceneEntriesInUse(0);
    }
#endif
    emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
}

EmberAfStatus emberAfScenesSetSceneCountAttribute(EndpointId endpoint, uint8_t newCount)
{
    return writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_COUNT_ATTRIBUTE_ID, "scene count", (uint8_t *) &newCount,
                                ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus emberAfScenesMakeValid(EndpointId endpoint, uint8_t sceneId, GroupId groupId)
{
    EmberAfStatus status;
    bool valid = true;

    // scene ID
    status = writeServerAttribute(endpoint, Scenes::Id, ZCL_CURRENT_SCENE_ATTRIBUTE_ID, "current scene", (uint8_t *) &sceneId,
                                  ZCL_INT8U_ATTRIBUTE_TYPE);
    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        return status;
    }

    // group ID
    status = writeServerAttribute(endpoint, Scenes::Id, ZCL_CURRENT_GROUP_ATTRIBUTE_ID, "current group", (uint8_t *) &groupId,
                                  ZCL_INT16U_ATTRIBUTE_TYPE);
    if (status != EMBER_ZCL_STATUS_SUCCESS)
    {
        return status;
    }

    status = writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid,
                                  ZCL_BOOLEAN_ATTRIBUTE_TYPE);
    return status;
}

EmberAfStatus emberAfScenesClusterMakeInvalidCallback(EndpointId endpoint)
{
    bool valid = false;
    return writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid,
                                ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

void emAfPluginScenesServerPrintInfo()
{
    uint8_t i;
    EmberAfSceneTableEntry entry;
    emberAfCorePrintln("using 0x%x out of 0x%x table slots", emberAfPluginScenesServerNumSceneEntriesInUse(),
                       MATTER_SCENES_TABLE_SIZE);
    for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
    {
        emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
        emberAfCorePrint("%x: ", i);
        if (entry.endpoint != EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
        {
            emberAfCorePrint("ep %x grp %2x scene %x tt %d", entry.endpoint, entry.groupId, entry.sceneId, entry.transitionTime);
            emberAfCorePrint(".%d", entry.transitionTime100ms);
#if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
            emberAfCorePrint(" name(%x)\"", emberAfStringLength(entry.name));
            emberAfCorePrintString(entry.name);
            emberAfCorePrint("\"");
#endif
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
            emberAfCorePrint(" on/off %x", entry.onOffValue);
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
            emberAfCorePrint(" lvl %x", entry.currentLevelValue);
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
            emberAfCorePrint(" therm %2x %2x %x", entry.occupiedCoolingSetpointValue, entry.occupiedHeatingSetpointValue,
                             entry.systemModeValue);
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
            emberAfCorePrint(" color %2x %2x", entry.currentXValue, entry.currentYValue);
            emberAfCorePrint(" %2x %x %x %x %2x %2x", entry.enhancedCurrentHueValue, entry.currentSaturationValue,
                             entry.colorLoopActiveValue, entry.colorLoopDirectionValue, entry.colorLoopTimeValue,
                             entry.colorTemperatureMiredsValue);
            emberAfCoreFlush();
#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
            emberAfCorePrint(" door %x", entry.lockStateValue);
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
            emberAfCorePrint(" Window percentage Lift %3u, Tilt %3u", entry.currentPositionLiftPercentageValue,
                             entry.currentPositionTiltPercentageValue);
            emberAfCorePrint(" Window percent100ths Lift %5u, Tilt %5u", entry.targetPositionLiftPercent100thsValue,
                             entry.targetPositionTiltPercent100thsValue);
#endif
        }
        emberAfCorePrintln("%s", "");
    }
}

bool emberAfScenesClusterAddSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                          const Commands::AddScene::DecodableType & commandData)
{
    auto & groupId            = commandData.groupId;
    auto & sceneId            = commandData.sceneId;
    auto & transitionTime     = commandData.transitionTime;
    auto & sceneName          = commandData.sceneName;
    auto & extensionFieldSets = commandData.extensionFieldSets;

    return emberAfPluginScenesServerParseAddScene(commandObj, emberAfCurrentCommand(), groupId, sceneId, transitionTime, sceneName,
                                                  extensionFieldSets);
}

bool emberAfScenesClusterViewSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                           const Commands::ViewScene::DecodableType & commandData)
{
    auto & groupId = commandData.groupId;
    auto & sceneId = commandData.sceneId;

    return emberAfPluginScenesServerParseViewScene(commandObj, emberAfCurrentCommand(), groupId, sceneId);
}

bool emberAfScenesClusterRemoveSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                             const Commands::RemoveScene::DecodableType & commandData)
{
    auto fabricIndex = commandObj->GetAccessingFabricIndex();
    auto & groupId   = commandData.groupId;
    auto & sceneId   = commandData.sceneId;

    EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
    CHIP_ERROR err       = CHIP_NO_ERROR;

    emberAfScenesClusterPrintln("RX: RemoveScene 0x%2x, 0x%x", groupId, sceneId);

    if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
    {
        status = EMBER_ZCL_STATUS_INVALID_COMMAND;
    }
    else
    {
        uint8_t i;
        for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
        {
            EmberAfSceneTableEntry entry;
            emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
            if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId && entry.sceneId == sceneId)
            {
                entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
                emberAfPluginScenesServerSaveSceneEntry(entry, i);
                emberAfPluginScenesServerDecrNumSceneEntriesInUse();
                emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
                status = EMBER_ZCL_STATUS_SUCCESS;
                break;
            }
        }
    }

    // Remove Scene commands are only responded to when they are addressed to a
    // single device.
    if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
    {
        {
            app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_REMOVE_SCENE_RESPONSE_COMMAND_ID };
            TLV::TLVWriter * writer       = nullptr;
            SuccessOrExit(err = commandObj->PrepareCommand(path));
            VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
            SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
            SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
            SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
            SuccessOrExit(err = commandObj->FinishCommand());
        }
    }
exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

bool emberAfScenesClusterRemoveAllScenesCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                 const Commands::RemoveAllScenes::DecodableType & commandData)
{
    auto fabricIndex = commandObj->GetAccessingFabricIndex();
    auto & groupId   = commandData.groupId;

    EmberAfStatus status = EMBER_ZCL_STATUS_INVALID_COMMAND;
    CHIP_ERROR err       = CHIP_NO_ERROR;

    emberAfScenesClusterPrintln("RX: RemoveAllScenes 0x%2x", groupId);

    if (isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
    {
        uint8_t i;
        status = EMBER_ZCL_STATUS_SUCCESS;
        for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
        {
            EmberAfSceneTableEntry entry;
            emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
            if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
            {
                entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
                emberAfPluginScenesServerSaveSceneEntry(entry, i);
                emberAfPluginScenesServerDecrNumSceneEntriesInUse();
            }
        }
        emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
    }

    // Remove All Scenes commands are only responded to when they are addressed
    // to a single device.
    if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
    {
        {
            app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_REMOVE_ALL_SCENES_RESPONSE_COMMAND_ID };
            TLV::TLVWriter * writer       = nullptr;
            SuccessOrExit(err = commandObj->PrepareCommand(path));
            VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
            SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
            SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
            SuccessOrExit(err = commandObj->FinishCommand());
        }
    }
exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

bool emberAfScenesClusterStoreSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                            const Commands::StoreScene::DecodableType & commandData)
{
    auto fabricIndex = commandObj->GetAccessingFabricIndex();
    auto & groupId   = commandData.groupId;
    auto & sceneId   = commandData.sceneId;

    EmberAfStatus status;
    CHIP_ERROR err = CHIP_NO_ERROR;
    emberAfScenesClusterPrintln("RX: StoreScene 0x%2x, 0x%x", groupId, sceneId);
    status = emberAfScenesClusterStoreCurrentSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);

    // Store Scene commands are only responded to when they are addressed to a
    // single device.
    if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
    {
        {
            app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_STORE_SCENE_RESPONSE_COMMAND_ID };
            TLV::TLVWriter * writer       = nullptr;
            SuccessOrExit(err = commandObj->PrepareCommand(path));
            VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
            SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
            SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
            SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
            SuccessOrExit(err = commandObj->FinishCommand());
        }
    }
exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

bool emberAfScenesClusterRecallSceneCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                             const Commands::RecallScene::DecodableType & commandData)
{
    auto fabricIndex = commandObj->GetAccessingFabricIndex();
    auto & groupId   = commandData.groupId;
    auto & sceneId   = commandData.sceneId;

    // NOTE: TransitionTime field in the RecallScene command is currently
    // ignored. Per Zigbee Alliance ZCL 7 (07-5123-07):
    //
    // "The transition time determines how long the tranition takes from the
    // old cluster state to the new cluster state. It is recommended that, where
    // possible (e.g., it is not possible for attributes with Boolean type),
    // a gradual transition SHOULD take place from the old to the new state
    // over this time. However, the exact transition is manufacturer dependent."
    //
    // The manufacturer-dependent implementation here is to immediately set
    // all attributes to their scene-specified values, without regard to the
    // value of TransitionTime.

    EmberAfStatus status;
    EmberStatus sendStatus = EMBER_SUCCESS;
    emberAfScenesClusterPrintln("RX: RecallScene 0x%2x, 0x%x", groupId, sceneId);
    status = emberAfScenesClusterRecallSavedSceneCallback(fabricIndex, emberAfCurrentEndpoint(), groupId, sceneId);
#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
    if (status == EMBER_ZCL_STATUS_SUCCESS)
    {
        emberAfPluginZllScenesServerRecallSceneZllExtensions(emberAfCurrentEndpoint());
    }
#endif
    sendStatus = emberAfSendImmediateDefaultResponse(status);
    if (EMBER_SUCCESS != sendStatus)
    {
        emberAfScenesClusterPrintln("Scenes: failed to send %s: 0x%x", "default_response", sendStatus);
    }
    return true;
}

bool emberAfScenesClusterGetSceneMembershipCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                    const Commands::GetSceneMembership::DecodableType & commandData)
{
    auto fabricIndex = commandObj->GetAccessingFabricIndex();
    auto & groupId   = commandData.groupId;

    CHIP_ERROR err       = CHIP_NO_ERROR;
    EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
    uint8_t sceneCount   = 0;
    uint8_t sceneList[MATTER_SCENES_TABLE_SIZE];

    emberAfScenesClusterPrintln("RX: GetSceneMembership 0x%2x", groupId);

    if (!isEndpointInGroup(fabricIndex, emberAfCurrentEndpoint(), groupId))
    {
        status = EMBER_ZCL_STATUS_INVALID_COMMAND;
    }

    if (status == EMBER_ZCL_STATUS_SUCCESS)
    {
        uint8_t i;
        for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
        {
            EmberAfSceneTableEntry entry;
            emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
            if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
            {
                sceneList[sceneCount] = entry.sceneId;
                sceneCount++;
            }
        }
        emberAfPutInt8uInResp(sceneCount);
        for (i = 0; i < sceneCount; i++)
        {
            emberAfPutInt8uInResp(sceneList[i]);
        }
    }

    {
        app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_GET_SCENE_MEMBERSHIP_RESPONSE_COMMAND_ID };
        TLV::TLVWriter * writer       = nullptr;
        SuccessOrExit(err = commandObj->PrepareCommand(path));
        VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
        SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
        SuccessOrExit(
            err = writer->Put(TLV::ContextTag(1),
                              static_cast<uint8_t>(MATTER_SCENES_TABLE_SIZE - emberAfPluginScenesServerNumSceneEntriesInUse())));
        SuccessOrExit(err = writer->Put(TLV::ContextTag(2), groupId));
        SuccessOrExit(err = writer->Put(TLV::ContextTag(3), sceneCount));
        SuccessOrExit(err = writer->Put(TLV::ContextTag(4), ByteSpan(sceneList, sceneCount)));
        SuccessOrExit(err = commandObj->FinishCommand());
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId,
                                                            uint8_t sceneId)
{
    EmberAfSceneTableEntry entry;
    uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;

    if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
    {
        return EMBER_ZCL_STATUS_INVALID_COMMAND;
    }

    for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
    {
        emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
        if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
        {
            index = i;
            break;
        }
        if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
        {
            index = i;
        }
    }

    // If the target index is still zero, the table is full.
    if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX)
    {
        return EMBER_ZCL_STATUS_RESOURCE_EXHAUSTED;
    }

    emberAfPluginScenesServerRetrieveSceneEntry(entry, index);

    // When creating a new entry or refreshing an existing one, the extension
    // fields are updated with the current state of other clusters on the device.
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
    entry.hasOnOffValue = readServerAttribute(endpoint, OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off", (uint8_t *) &entry.onOffValue,
                                              sizeof(entry.onOffValue));
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
    entry.hasCurrentLevelValue = readServerAttribute(endpoint, LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level",
                                                     (uint8_t *) &entry.currentLevelValue, sizeof(entry.currentLevelValue));
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
    entry.hasOccupiedCoolingSetpointValue =
        readServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, "occupied cooling setpoint",
                            (uint8_t *) &entry.occupiedCoolingSetpointValue, sizeof(entry.occupiedCoolingSetpointValue));
    entry.hasOccupiedHeatingSetpointValue =
        readServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, "occupied heating setpoint",
                            (uint8_t *) &entry.occupiedHeatingSetpointValue, sizeof(entry.occupiedHeatingSetpointValue));
    entry.hasSystemModeValue = readServerAttribute(endpoint, Thermostat::Id, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode",
                                                   (uint8_t *) &entry.systemModeValue, sizeof(entry.systemModeValue));
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
    entry.hasCurrentXValue = readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID, "current x",
                                                 (uint8_t *) &entry.currentXValue, sizeof(entry.currentXValue));
    entry.hasCurrentYValue = readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID, "current y",
                                                 (uint8_t *) &entry.currentYValue, sizeof(entry.currentYValue));
    entry.hasEnhancedCurrentHueValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID, "enhanced current hue",
                            (uint8_t *) &entry.enhancedCurrentHueValue, sizeof(entry.enhancedCurrentHueValue));
    entry.hasCurrentSaturationValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, "current saturation",
                            (uint8_t *) &entry.currentSaturationValue, sizeof(entry.currentSaturationValue));
    entry.hasColorLoopActiveValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID, "color loop active",
                            (uint8_t *) &entry.colorLoopActiveValue, sizeof(entry.colorLoopActiveValue));
    entry.hasColorLoopDirectionValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID, "color loop direction",
                            (uint8_t *) &entry.colorLoopDirectionValue, sizeof(entry.colorLoopDirectionValue));
    entry.hasColorLoopTimeValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID, "color loop time",
                            (uint8_t *) &entry.colorLoopTimeValue, sizeof(entry.colorLoopTimeValue));
    entry.hasColorTemperatureMiredsValue =
        readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID, "color temp mireds",
                            (uint8_t *) &entry.colorTemperatureMiredsValue, sizeof(entry.colorTemperatureMiredsValue));
#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
    entry.hasLockStateValue = readServerAttribute(endpoint, DoorLock::Id, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state",
                                                  (uint8_t *) &entry.lockStateValue, sizeof(entry.lockStateValue));
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
    entry.hasCurrentPositionLiftPercentageValue = readServerAttribute(
        endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_LIFT_PERCENTAGE_ATTRIBUTE_ID, "currentPositionLiftPercentage",
        (uint8_t *) &entry.currentPositionLiftPercentageValue, sizeof(entry.currentPositionLiftPercentageValue));
    entry.hasCurrentPositionTiltPercentageValue = readServerAttribute(
        endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_TILT_PERCENTAGE_ATTRIBUTE_ID, "currentPositionTiltPercentage",
        (uint8_t *) &entry.currentPositionTiltPercentageValue, sizeof(entry.currentPositionTiltPercentageValue));
    entry.hasTargetPositionLiftPercent100thsValue = readServerAttribute(
        endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_LIFT_PERCENT100_THS_ATTRIBUTE_ID, "targetPositionLiftPercent100ths",
        (uint8_t *) &entry.targetPositionLiftPercent100thsValue, sizeof(entry.targetPositionLiftPercent100thsValue));
    entry.hasTargetPositionTiltPercent100thsValue = readServerAttribute(
        endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_TILT_PERCENT100_THS_ATTRIBUTE_ID, "targetPositionTiltPercent100ths",
        (uint8_t *) &entry.targetPositionTiltPercent100thsValue, sizeof(entry.targetPositionTiltPercent100thsValue));
#endif

    // When creating a new entry, the name is set to the null string (i.e., the
    // length is set to zero) and the transition time is set to zero.  The scene
    // count must be increased and written to the attribute table when adding a
    // new scene.  Otherwise, these fields and the count are left alone.
    if (i != index)
    {
        entry.endpoint = endpoint;
        entry.groupId  = groupId;
        entry.sceneId  = sceneId;
#if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
        entry.name[0] = 0;
#endif
        entry.transitionTime      = 0;
        entry.transitionTime100ms = 0;
        emberAfPluginScenesServerIncrNumSceneEntriesInUse();
        emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
    }

    // Save the scene entry and mark is as valid by storing its scene and group
    // ids in the attribute table and setting valid to true.
    emberAfPluginScenesServerSaveSceneEntry(entry, index);
    emberAfScenesMakeValid(endpoint, sceneId, groupId);
    return EMBER_ZCL_STATUS_SUCCESS;
}

EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::FabricIndex fabricIndex, EndpointId endpoint, GroupId groupId,
                                                           uint8_t sceneId)
{
    if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
    {
        return EMBER_ZCL_STATUS_INVALID_COMMAND;
    }

    uint8_t i;
    for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
    {
        EmberAfSceneTableEntry entry;
        emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
        if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
        {
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
            if (entry.hasOnOffValue)
            {
                writeServerAttribute(endpoint, OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off", (uint8_t *) &entry.onOffValue,
                                     ZCL_BOOLEAN_ATTRIBUTE_TYPE);
            }
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
            if (entry.hasCurrentLevelValue)
            {
                writeServerAttribute(endpoint, LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level",
                                     (uint8_t *) &entry.currentLevelValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
            if (entry.hasOccupiedCoolingSetpointValue)
            {
                writeServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID,
                                     "occupied cooling setpoint", (uint8_t *) &entry.occupiedCoolingSetpointValue,
                                     ZCL_INT16S_ATTRIBUTE_TYPE);
            }
            if (entry.hasOccupiedHeatingSetpointValue)
            {
                writeServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID,
                                     "occupied heating setpoint", (uint8_t *) &entry.occupiedHeatingSetpointValue,
                                     ZCL_INT16S_ATTRIBUTE_TYPE);
            }
            if (entry.hasSystemModeValue)
            {
                writeServerAttribute(endpoint, Thermostat::Id, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode",
                                     (uint8_t *) &entry.systemModeValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
            if (entry.hasCurrentXValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID, "current x",
                                     (uint8_t *) &entry.currentXValue, ZCL_INT16U_ATTRIBUTE_TYPE);
            }
            if (entry.hasCurrentYValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID, "current y",
                                     (uint8_t *) &entry.currentYValue, ZCL_INT16U_ATTRIBUTE_TYPE);
            }

            if (entry.hasEnhancedCurrentHueValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID,
                                     "enhanced current hue", (uint8_t *) &entry.enhancedCurrentHueValue, ZCL_INT16U_ATTRIBUTE_TYPE);
            }
            if (entry.hasCurrentSaturationValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
                                     "current saturation", (uint8_t *) &entry.currentSaturationValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
            if (entry.hasColorLoopActiveValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID,
                                     "color loop active", (uint8_t *) &entry.colorLoopActiveValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
            if (entry.hasColorLoopDirectionValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID,
                                     "color loop direction", (uint8_t *) &entry.colorLoopDirectionValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
            if (entry.hasColorLoopTimeValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID, "color loop time",
                                     (uint8_t *) &entry.colorLoopTimeValue, ZCL_INT16U_ATTRIBUTE_TYPE);
            }
            if (entry.hasColorTemperatureMiredsValue)
            {
                writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
                                     "color temp mireds", (uint8_t *) &entry.colorTemperatureMiredsValue,
                                     ZCL_INT16U_ATTRIBUTE_TYPE);
            }
#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
            if (entry.hasLockStateValue)
            {
                writeServerAttribute(endpoint, DoorLock::Id, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state",
                                     (uint8_t *) &entry.lockStateValue, ZCL_INT8U_ATTRIBUTE_TYPE);
            }
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
            if (entry.hasCurrentPositionLiftPercentageValue)
            {
                writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_LIFT_PERCENTAGE_ATTRIBUTE_ID,
                                     "CurrentPositionLiftPercentage", (uint8_t *) &entry.currentPositionLiftPercentageValue,
                                     ZCL_INT8U_ATTRIBUTE_TYPE);
            }
            if (entry.hasCurrentPositionTiltPercentageValue)
            {
                writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_TILT_PERCENTAGE_ATTRIBUTE_ID,
                                     "CurrentPositionTiltPercentage", (uint8_t *) &entry.currentPositionTiltPercentageValue,
                                     ZCL_INT8U_ATTRIBUTE_TYPE);
            }
            if (entry.hasTargetPositionLiftPercent100thsValue)
            {
                writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_LIFT_PERCENT100_THS_ATTRIBUTE_ID,
                                     "TargetPositionLiftPercent100ths", (uint8_t *) &entry.targetPositionLiftPercent100thsValue,
                                     ZCL_INT16U_ATTRIBUTE_TYPE);
            }
            if (entry.hasTargetPositionTiltPercent100thsValue)
            {
                writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_TILT_PERCENT100_THS_ATTRIBUTE_ID,
                                     "TargetPositionTiltPercent100ths", (uint8_t *) &entry.targetPositionTiltPercent100thsValue,
                                     ZCL_INT16U_ATTRIBUTE_TYPE);
            }
#endif
            emberAfScenesMakeValid(endpoint, sceneId, groupId);
            return EMBER_ZCL_STATUS_SUCCESS;
        }
    }

    return EMBER_ZCL_STATUS_NOT_FOUND;
}

bool emberAfPluginScenesServerParseAddScene(
    app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, GroupId groupId, uint8_t sceneId, uint16_t transitionTime,
    const CharSpan & sceneName, const app::DataModel::DecodableList<Structs::ExtensionFieldSet::DecodableType> & extensionFieldSets)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    EmberAfSceneTableEntry entry;
    EmberAfStatus status;
    bool enhanced       = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
    auto fabricIndex    = commandObj->GetAccessingFabricIndex();
    EndpointId endpoint = cmd->apsFrame->destinationEndpoint;
    uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;

    emberAfScenesClusterPrintln("RX: %pAddScene 0x%2x, 0x%x, 0x%2x, \"%.*s\"", (enhanced ? "Enhanced" : ""), groupId, sceneId,
                                transitionTime, static_cast<int>(sceneName.size()), sceneName.data());

    auto fieldSetIter = extensionFieldSets.begin();

    // Add Scene commands can only reference groups to which we belong.
    if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
    {
        status = EMBER_ZCL_STATUS_INVALID_COMMAND;
        goto kickout;
    }

    for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
    {
        emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
        if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
        {
            index = i;
            break;
        }
        if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
        {
            index = i;
        }
    }

    // If the target index is still zero, the table is full.
    if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX)
    {
        status = EMBER_ZCL_STATUS_RESOURCE_EXHAUSTED;
        goto kickout;
    }

    emberAfPluginScenesServerRetrieveSceneEntry(entry, index);

    // The transition time is specified in seconds in the regular version of the
    // command and tenths of a second in the enhanced version.
    if (enhanced)
    {
        entry.transitionTime      = transitionTime / 10;
        entry.transitionTime100ms = (uint8_t)(transitionTime - entry.transitionTime * 10);
    }
    else
    {
        entry.transitionTime      = transitionTime;
        entry.transitionTime100ms = 0;
    }

#if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
    emberAfCopyString(entry.name, Uint8::from_const_char(sceneName.data()), ZCL_SCENES_CLUSTER_MAXIMUM_NAME_LENGTH);
#endif

    // When adding a new scene, wipe out all of the extensions before parsing the
    // extension field sets data.
    if (i != index)
    {
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
        entry.hasOnOffValue = false;
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
        entry.hasCurrentLevelValue = false;
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
        entry.hasOccupiedCoolingSetpointValue = false;
        entry.hasOccupiedHeatingSetpointValue = false;
        entry.hasSystemModeValue              = false;
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
        entry.hasCurrentXValue               = false;
        entry.hasCurrentYValue               = false;
        entry.hasEnhancedCurrentHueValue     = false;
        entry.hasCurrentSaturationValue      = false;
        entry.hasColorLoopActiveValue        = false;
        entry.hasColorLoopDirectionValue     = false;
        entry.hasColorLoopTimeValue          = false;
        entry.hasColorTemperatureMiredsValue = false;
#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
        entry.hasLockStateValue = false;
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
        entry.hasCurrentPositionLiftPercentageValue   = false;
        entry.hasCurrentPositionTiltPercentageValue   = false;
        entry.hasTargetPositionLiftPercent100thsValue = false;
        entry.hasTargetPositionTiltPercent100thsValue = false;
#endif
    }

    while (fieldSetIter.Next())
    {
        auto & fieldSet = fieldSetIter.GetValue();

        ClusterId clusterId = fieldSet.clusterId;

        // TODO: We need to encode scene field sets in TLV.
        // https://github.com/project-chip/connectedhomeip/issues/10334
        switch (clusterId)
        {
#if 0
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
        case OnOff::Id:
            // We only know of one extension for the On/Off cluster and it is just one
            // byte, which means we can skip some logic for this cluster.  If other
            // extensions are added in this cluster, more logic will be needed here.
            entry.hasOnOffValue = true;
            entry.onOffValue    = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            break;
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
        case LevelControl::Id:
            // We only know of one extension for the Level Control cluster and it is
            // just one byte, which means we can skip some logic for this cluster.  If
            // other extensions are added in this cluster, more logic will be needed
            // here.
            entry.hasCurrentLevelValue = true;
            entry.currentLevelValue    = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            break;
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
        case Thermostat::Id:
            if (length < 2)
            {
                break;
            }
            entry.hasOccupiedCoolingSetpointValue = true;
            entry.occupiedCoolingSetpointValue =
                (int16_t) emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
            length                  = static_cast<uint8_t>(length - 2);
            if (length < 2)
            {
                break;
            }
            entry.hasOccupiedHeatingSetpointValue = true;
            entry.occupiedHeatingSetpointValue =
                (int16_t) emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
            length                  = static_cast<uint8_t>(length - 2);
            if (length < 1)
            {
                break;
            }
            entry.hasSystemModeValue = true;
            entry.systemModeValue    = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            // If additional Thermostat extensions are added, adjust the index and
            // length variables here.
            break;
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
        case ColorControl::Id:
            if (length < 2)
            {
                break;
            }
            entry.hasCurrentXValue  = true;
            entry.currentXValue     = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
            length                  = static_cast<uint8_t>(length - 2);
            if (length < 2)
            {
                break;
            }
            entry.hasCurrentYValue = true;
            entry.currentYValue    = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            if (enhanced)
            {
                extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
                length                  = static_cast<uint8_t>(length - 2);
                ;
                if (length < 2)
                {
                    break;
                }
                entry.hasEnhancedCurrentHueValue = true;
                entry.enhancedCurrentHueValue =
                    emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
                extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
                length                  = static_cast<uint8_t>(length - 2);
                if (length < 1)
                {
                    break;
                }
                entry.hasCurrentSaturationValue = true;
                entry.currentSaturationValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
                extensionFieldSetsIndex++;
                length--;
                if (length < 1)
                {
                    break;
                }
                entry.hasColorLoopActiveValue = true;
                entry.colorLoopActiveValue    = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
                extensionFieldSetsIndex++;
                length--;
                if (length < 1)
                {
                    break;
                }
                entry.hasColorLoopDirectionValue = true;
                entry.colorLoopDirectionValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
                extensionFieldSetsIndex++;
                length--;
                if (length < 2)
                {
                    break;
                }
                entry.hasColorLoopTimeValue = true;
                entry.colorLoopTimeValue    = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
                extensionFieldSetsIndex     = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
                length                      = static_cast<uint8_t>(length - 2);
                if (length < 2)
                {
                    break;
                }
                entry.hasColorTemperatureMiredsValue = true;
                entry.colorTemperatureMiredsValue =
                    emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            }
            // If additional Color Control extensions are added, adjust the index and
            // length variables here.
            break;
#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
        case DoorLock::Id:
            // We only know of one extension for the Door Lock cluster and it is just
            // one byte, which means we can skip some logic for this cluster.  If
            // other extensions are added in this cluster, more logic will be needed
            // here.
            entry.hasLockStateValue = true;
            entry.lockStateValue    = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            break;
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
        case WindowCovering::Id:
            // If we're here, we know we have at least one byte, so we can skip the
            // length check for the first field.
            entry.hasCurrentPositionLiftPercentageValue = true;
            entry.currentPositionLiftPercentageValue =
                emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex++;
            length--;
            if (length < 1)
            {
                break;
            }
            entry.hasCurrentPositionTiltPercentageValue = true;
            entry.currentPositionTiltPercentageValue =
                emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex++;
            length--;
            if (length < 2)
            {
                break;
            }
            entry.hasTargetPositionLiftPercent100thsValue = true;
            entry.targetPositionLiftPercent100thsValue =
                emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            extensionFieldSetsIndex = static_cast<uint16_t>(extensionFieldSetsIndex + 2);
            length                  = static_cast<uint8_t>(length - 2);
            if (length < 2)
            {
                break;
            }
            entry.hasTargetPositionTiltPercent100thsValue = true;
            entry.targetPositionTiltPercent100thsValue =
                emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
            // If additional Window Covering extensions are added, adjust the index
            // and length variables here.
            break;
#endif
#endif // if 0 disabling all the code.
        default:
            break;
        }
    }

    if (fieldSetIter.GetStatus() != CHIP_NO_ERROR)
    {
        status = EMBER_ZCL_STATUS_MALFORMED_COMMAND;
        goto kickout;
    }

    // If we got this far, we either added a new entry or updated an existing one.
    // If we added, store the basic data and increment the scene count.  In either
    // case, save the entry.
    if (i != index)
    {
        entry.endpoint = endpoint;
        entry.groupId  = groupId;
        entry.sceneId  = sceneId;
        emberAfPluginScenesServerIncrNumSceneEntriesInUse();
        emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
    }
    emberAfPluginScenesServerSaveSceneEntry(entry, index);
    status = EMBER_ZCL_STATUS_SUCCESS;

kickout:
    // Add Scene commands are only responded to when they are addressed to a
    // single device.
    if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
    {
        return true;
    }
    {
        app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_ADD_SCENE_RESPONSE_COMMAND_ID };
        if (enhanced)
        {
            path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_ENHANCED_ADD_SCENE_RESPONSE_COMMAND_ID };
        }
        TLV::TLVWriter * writer = nullptr;
        SuccessOrExit(err = commandObj->PrepareCommand(path));
        VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
        SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
        SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
        SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
        SuccessOrExit(err = commandObj->FinishCommand());
    }

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

bool emberAfPluginScenesServerParseViewScene(app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, GroupId groupId,
                                             uint8_t sceneId)
{
    CHIP_ERROR err               = CHIP_NO_ERROR;
    EmberAfSceneTableEntry entry = {};
    EmberAfStatus status         = EMBER_ZCL_STATUS_NOT_FOUND;
    bool enhanced                = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
    FabricIndex fabricIndex      = commandObj->GetAccessingFabricIndex();
    EndpointId endpoint          = cmd->apsFrame->destinationEndpoint;

    emberAfScenesClusterPrintln("RX: %pViewScene 0x%2x, 0x%x", (enhanced ? "Enhanced" : ""), groupId, sceneId);

    // View Scene commands can only reference groups which we belong to.
    if (!isEndpointInGroup(fabricIndex, endpoint, groupId))
    {
        status = EMBER_ZCL_STATUS_INVALID_COMMAND;
    }
    else
    {
        uint8_t i;
        for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
        {
            emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
            if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
            {
                status = EMBER_ZCL_STATUS_SUCCESS;
                break;
            }
        }
    }

    // The status, group id, and scene id are always included in the response, but
    // the transition time, name, and extension fields are only included if the
    // scene was found.
    app::ConcreteCommandPath path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_VIEW_SCENE_RESPONSE_COMMAND_ID };
    if (enhanced)
    {
        path = { emberAfCurrentEndpoint(), Scenes::Id, ZCL_ENHANCED_VIEW_SCENE_RESPONSE_COMMAND_ID };
    }
    TLV::TLVWriter * writer = nullptr;
    SuccessOrExit(err = commandObj->PrepareCommand(path));
    VerifyOrExit((writer = commandObj->GetCommandDataIBTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
    SuccessOrExit(err = writer->Put(TLV::ContextTag(0), status));
    SuccessOrExit(err = writer->Put(TLV::ContextTag(1), groupId));
    SuccessOrExit(err = writer->Put(TLV::ContextTag(2), sceneId));
    SuccessOrExit(err = writer->Put(TLV::ContextTag(3),
                                    static_cast<uint16_t>(enhanced ? entry.transitionTime * 10 + entry.transitionTime100ms
                                                                   : entry.transitionTime)));
#if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
    SuccessOrExit(err = writer->Put(TLV::ContextTag(4), entry.name));
#else
    SuccessOrExit(err = writer->PutString(TLV::ContextTag(4), ""));
#endif
    // #6620: Need the build the array for response.
    SuccessOrExit(err = writer->Put(TLV::ContextTag(5), ByteSpan(nullptr, 0)));
    SuccessOrExit(err = commandObj->FinishCommand());

    /*
        if (status == EMBER_ZCL_STATUS_SUCCESS)
        {
            // The transition time is returned in seconds in the regular version of the
            // command and tenths of a second in the enhanced version.
            emberAfPutInt16uInResp(
                static_cast<uint16_t>(enhanced ? entry.transitionTime * 10 + entry.transitionTime100ms : entry.transitionTime));
    #if defined(MATTER_CLUSTER_SCENE_NAME_SUPPORT) && MATTER_CLUSTER_SCENE_NAME_SUPPORT
            emberAfPutStringInResp(entry.name);
    #else
            emberAfPutInt8uInResp(0); // name length
    #endif
    #ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
            if (entry.hasOnOffValue)
            {
                emberAfPutInt16uInResp(OnOff::Id);
                emberAfPutInt8uInResp(1); // length
                emberAfPutInt8uInResp(entry.onOffValue);
            }
    #endif
    #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
            if (entry.hasCurrentLevelValue)
            {
                emberAfPutInt16uInResp(LevelControl::Id);
                emberAfPutInt8uInResp(1); // length
                emberAfPutInt8uInResp(entry.currentLevelValue);
            }
    #endif
    #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
            if (entry.hasOccupiedCoolingSetpointValue)
            {
                uint8_t * length;
                emberAfPutInt16uInResp(Thermostat::Id);
                length = &appResponseData[appResponseLength];
                emberAfPutInt8uInResp(0); // temporary length
                emberAfPutInt16sInResp(entry.occupiedCoolingSetpointValue);
                *length += 2;
                if (entry.hasOccupiedHeatingSetpointValue)
                {
                    emberAfPutInt16sInResp(entry.occupiedHeatingSetpointValue);
                    *length += 2;
                    if (entry.hasSystemModeValue)
                    {
                        emberAfPutInt8uInResp(entry.systemModeValue);
                        (*length)++;
                    }
                }
            }
    #endif
    #ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
            if (entry.hasCurrentXValue)
            {
                uint8_t * length;
                emberAfPutInt16uInResp(ColorControl::Id);
                length = &appResponseData[appResponseLength];
                emberAfPutInt8uInResp(0); // temporary length
                emberAfPutInt16uInResp(entry.currentXValue);
                *length = static_cast<uint8_t>(*length + 2);
                if (entry.hasCurrentYValue)
                {
                    emberAfPutInt16uInResp(entry.currentYValue);
                    *length = static_cast<uint8_t>(*length + 2);
                    if (enhanced)
                    {
                        if (entry.hasEnhancedCurrentHueValue)
                        {
                            emberAfPutInt16uInResp(entry.enhancedCurrentHueValue);
                            *length = static_cast<uint8_t>(*length + 2);
                            if (entry.hasCurrentSaturationValue)
                            {
                                emberAfPutInt8uInResp(entry.currentSaturationValue);
                                (*length)++;
                                if (entry.hasColorLoopActiveValue)
                                {
                                    emberAfPutInt8uInResp(entry.colorLoopActiveValue);
                                    (*length)++;
                                    if (entry.hasColorLoopDirectionValue)
                                    {
                                        emberAfPutInt8uInResp(entry.colorLoopDirectionValue);
                                        (*length)++;
                                        if (entry.hasColorLoopTimeValue)
                                        {
                                            emberAfPutInt16uInResp(entry.colorLoopTimeValue);
                                            *length = static_cast<uint8_t>(*length + 2);
                                            if (entry.hasColorTemperatureMiredsValue)
                                            {
                                                emberAfPutInt16uInResp(entry.colorTemperatureMiredsValue);
                                                *length = static_cast<uint8_t>(*length + 2);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
    #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
    #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
            if (entry.hasLockStateValue)
            {
                emberAfPutInt16uInResp(DoorLock::Id);
                emberAfPutInt8uInResp(1); // length
                emberAfPutInt8uInResp(entry.lockStateValue);
            }
    #endif
    #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
            if (entry.hasCurrentPositionLiftPercentageValue)
            {
                uint8_t * length;
                emberAfPutInt16uInResp(WindowCovering::Id);
                length = &appResponseData[appResponseLength];
                emberAfPutInt8uInResp(0); // temporary length
                emberAfPutInt8uInResp(entry.currentPositionLiftPercentageValue);
                (*length)++;
                if (entry.hasCurrentPositionTiltPercentageValue)
                {
                    emberAfPutInt8uInResp(entry.currentPositionTiltPercentageValue);
                    (*length)++;
                    if (entry.hasTargetPositionLiftPercent100thsValue)
                    {
                        emberAfPutInt16uInResp(entry.targetPositionLiftPercent100thsValue);
                        *length = static_cast<uint8_t>(*length + 2);
                        if (entry.hasTargetPositionTiltPercent100thsValue)
                        {
                            emberAfPutInt16uInResp(entry.targetPositionTiltPercent100thsValue);
                            *length = static_cast<uint8_t>(*length + 2);
                        }
                    }
                }
            }
    #endif
        }

    // View Scene commands are only responded to when they are addressed to a
    // single device.
    if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
    {
        return true;
    }
    sendStatus = emberAfSendResponse();
    if (EMBER_SUCCESS != sendStatus)
    {
        emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "view_scene", sendStatus);
    }
    */

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(Zcl, "Failed to encode response command.");
    }
    return true;
}

void emberAfScenesClusterRemoveScenesInGroupCallback(EndpointId endpoint, GroupId groupId)
{
    uint8_t i;
    for (i = 0; i < MATTER_SCENES_TABLE_SIZE; i++)
    {
        EmberAfSceneTableEntry entry;
        emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
        if (entry.endpoint == endpoint && entry.groupId == groupId)
        {
            entry.groupId  = ZCL_SCENES_GLOBAL_SCENE_GROUP_ID;
            entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
            emberAfPluginScenesServerSaveSceneEntry(entry, i);
            emberAfPluginScenesServerDecrNumSceneEntriesInUse();
            emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
        }
    }
}

void MatterScenesPluginServerInitCallback() {}
