/*
 *
 *    Copyright (c) 2022 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 "AllClustersCommandDelegate.h"

#include <app-common/zap-generated/attributes/Accessors.h>
#include <app/EventLogging.h>
#include <app/clusters/basic-information/CodegenIntegration.h>
#include <app/clusters/boolean-state-configuration-server/CodegenIntegration.h>
#include <app/clusters/boolean-state-server/CodegenIntegration.h>
#include <app/clusters/general-diagnostics-server/CodegenIntegration.h>
#include <app/clusters/occupancy-sensor-server/CodegenIntegration.h>
#include <app/clusters/refrigerator-alarm-server/refrigerator-alarm-server.h>
#include <app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h>
#include <app/clusters/software-diagnostics-server/software-fault-listener.h>
#include <app/clusters/switch-server/switch-server.h>
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>
#include <platform/PlatformManager.h>
#include <soil-measurement-stub.h>

#include "ButtonEventsSimulator.h"
#include <air-quality-instance.h>
#include <dishwasher-mode.h>
#include <laundry-washer-mode.h>
#include <operational-state-delegate-impl.h>
#include <oven-modes.h>
#include <oven-operational-state-delegate.h>
#include <rvc-modes.h>

#include <memory>
#include <string>
#include <utility>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer;

namespace {

std::unique_ptr<ButtonEventsSimulator> sButtonSimulatorInstance{ nullptr };

bool HasNumericField(Json::Value & jsonValue, const std::string & field)
{
    return jsonValue.isMember(field) && jsonValue[field].isNumeric();
}

uint8_t GetNumberOfSwitchPositions(EndpointId endpointId)
{
    // TODO: Move to using public API of cluster.
    uint8_t numPositions = 0;

    // On failure, the numPositions won't be changed, so 0 returned.
    // This attribute is a configuration value for the cluster, it can not be changed once the cluster is created.
    // This is why the cluster does not provide a getter for this attribute.
    // We read this via ember (i.e. defaults that were set during codegen startup)
    RETURN_SAFELY_IGNORED Switch::Attributes::NumberOfPositions::Get(endpointId, &numPositions);

    return numPositions;
}

/**
 * Named pipe handler for simulated long press
 *
 * Usage example:
 *   echo '{"Name": "SimulateLongPress", "EndpointId": 3, "ButtonId": 1, "LongPressDelayMillis": 800,
 * "LongPressDurationMillis": 1000}' > /tmp/chip_all_clusters_fifo_1146610
 *
 * JSON Arguments:
 *   - "Name": Must be "SimulateLongPress"
 *   - "EndpointId": ID of endpoint having a switch cluster
 *   - "ButtonId": switch position in the switch cluster for "down" button (not idle)
 *   - "LongPressDelayMillis": Time in milliseconds before the LongPress
 *   - "LongPressDurationMillis": Total duration in milliseconds from start of the press to LongRelease
 *   - "FeatureMap": The feature map to simulate
 *
 * @param jsonValue - JSON payload from named pipe
 */
void HandleSimulateLongPress(Json::Value & jsonValue)
{
    if (sButtonSimulatorInstance != nullptr)
    {
        ChipLogError(NotSpecified, "Button simulation already in progress! Ignoring request.");
        return;
    }

    bool hasEndpointId              = HasNumericField(jsonValue, "EndpointId");
    bool hasButtonId                = HasNumericField(jsonValue, "ButtonId");
    bool hasLongPressDelayMillis    = HasNumericField(jsonValue, "LongPressDelayMillis");
    bool hasLongPressDurationMillis = HasNumericField(jsonValue, "LongPressDurationMillis");
    bool hasFeatureMap              = HasNumericField(jsonValue, "FeatureMap");
    if (!hasEndpointId || !hasButtonId || !hasLongPressDelayMillis || !hasLongPressDurationMillis || !hasFeatureMap)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified,
                     "Missing or invalid value for one of EndpointId, ButtonId, LongPressDelayMillis, LongPressDurationMillis or "
                     "FeatureMap in %s",
                     inputJson.c_str());
        return;
    }

    EndpointId endpointId = static_cast<EndpointId>(jsonValue["EndpointId"].asUInt());
    uint8_t buttonId      = static_cast<uint8_t>(jsonValue["ButtonId"].asUInt());

    uint8_t numPositions = GetNumberOfSwitchPositions(endpointId);
    if (buttonId >= numPositions)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Invalid ButtonId (out of range) in %s", inputJson.c_str());
        return;
    }

    System::Clock::Milliseconds32 longPressDelayMillis{ static_cast<unsigned>(jsonValue["LongPressDelayMillis"].asUInt()) };
    System::Clock::Milliseconds32 longPressDurationMillis{ static_cast<unsigned>(jsonValue["LongPressDurationMillis"].asUInt()) };
    uint32_t featureMap  = static_cast<uint32_t>(jsonValue["FeatureMap"].asUInt());
    auto buttonSimulator = std::make_unique<ButtonEventsSimulator>();

    bool success = buttonSimulator->SetMode(ButtonEventsSimulator::Mode::kModeLongPress)
                       .SetLongPressDelayMillis(longPressDelayMillis)
                       .SetLongPressDurationMillis(longPressDurationMillis)
                       .SetIdleButtonId(0)
                       .SetPressedButtonId(buttonId)
                       .SetEndpointId(endpointId)
                       .SetFeatureMap(featureMap)
                       .Execute([]() { sButtonSimulatorInstance.reset(); });

    if (!success)
    {
        ChipLogError(NotSpecified, "Failed to start execution of button simulator!");
        return;
    }

    sButtonSimulatorInstance = std::move(buttonSimulator);
}

/**
 * Named pipe handler for simulated multi-press.
 *
 * Usage example:
 *   echo '{"Name": "SimulateMultiPress", "EndpointId": 3, "ButtonId": 1, "MultiPressPressedTimeMillis": 100,
 * "MultiPressReleasedTimeMillis": 350, "MultiPressNumPresses": 2, "FeatureMap": 58}' > /tmp/chip_all_clusters_fifo_1146610
 *
 * JSON Arguments:
 *   - "Name": Must be "SimulateActionSwitchMultiPress"
 *   - "EndpointId": ID of endpoint having a switch cluster
 *   - "ButtonId": switch position in the switch cluster for "down" button (not idle)
 *   - "MultiPressPressedTimeMillis": Pressed time in milliseconds for each press
 *   - "MultiPressReleasedTimeMillis": Released time in milliseconds after each press
 *   - "MultiPressNumPresses": Number of presses to simulate
 *   - "FeatureMap": The feature map to simulate
 *   - "MultiPressMax": max number of presses (from attribute).
 *
 * @param jsonValue - JSON payload from named pipe
 */
void HandleSimulateMultiPress(Json::Value & jsonValue)
{
    if (sButtonSimulatorInstance != nullptr)
    {
        ChipLogError(NotSpecified, "Button simulation already in progress! Ignoring request.");
        return;
    }

    bool hasEndpointId                   = HasNumericField(jsonValue, "EndpointId");
    bool hasButtonId                     = HasNumericField(jsonValue, "ButtonId");
    bool hasMultiPressPressedTimeMillis  = HasNumericField(jsonValue, "MultiPressPressedTimeMillis");
    bool hasMultiPressReleasedTimeMillis = HasNumericField(jsonValue, "MultiPressReleasedTimeMillis");
    bool hasMultiPressNumPresses         = HasNumericField(jsonValue, "MultiPressNumPresses");
    bool hasFeatureMap                   = HasNumericField(jsonValue, "FeatureMap");
    bool hasMultiPressMax                = HasNumericField(jsonValue, "MultiPressMax");
    if (!hasEndpointId || !hasButtonId || !hasMultiPressPressedTimeMillis || !hasMultiPressReleasedTimeMillis ||
        !hasMultiPressNumPresses || !hasFeatureMap || !hasMultiPressMax)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified,
                     "Missing or invalid value for one of EndpointId, ButtonId, MultiPressPressedTimeMillis, "
                     "MultiPressReleasedTimeMillis, MultiPressNumPresses, FeatureMap or MultiPressMax in %s",
                     inputJson.c_str());
        return;
    }

    EndpointId endpointId = static_cast<EndpointId>(jsonValue["EndpointId"].asUInt());
    uint8_t buttonId      = static_cast<uint8_t>(jsonValue["ButtonId"].asUInt());

    uint8_t numPositions = GetNumberOfSwitchPositions(endpointId);
    if (buttonId >= numPositions)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Invalid ButtonId (out of range) in %s", inputJson.c_str());
        return;
    }

    System::Clock::Milliseconds32 multiPressPressedTimeMillis{ static_cast<unsigned>(
        jsonValue["MultiPressPressedTimeMillis"].asUInt()) };
    System::Clock::Milliseconds32 multiPressReleasedTimeMillis{ static_cast<unsigned>(
        jsonValue["MultiPressReleasedTimeMillis"].asUInt()) };
    uint8_t multiPressNumPresses = static_cast<uint8_t>(jsonValue["MultiPressNumPresses"].asUInt());
    uint32_t featureMap          = static_cast<uint32_t>(jsonValue["FeatureMap"].asUInt());
    uint8_t multiPressMax        = static_cast<uint8_t>(jsonValue["MultiPressMax"].asUInt());
    auto buttonSimulator         = std::make_unique<ButtonEventsSimulator>();

    bool success = buttonSimulator->SetMode(ButtonEventsSimulator::Mode::kModeMultiPress)
                       .SetMultiPressPressedTimeMillis(multiPressPressedTimeMillis)
                       .SetMultiPressReleasedTimeMillis(multiPressReleasedTimeMillis)
                       .SetMultiPressNumPresses(multiPressNumPresses)
                       .SetIdleButtonId(0)
                       .SetPressedButtonId(buttonId)
                       .SetEndpointId(endpointId)
                       .SetFeatureMap(featureMap)
                       .SetMultiPressMax(multiPressMax)
                       .Execute([]() { sButtonSimulatorInstance.reset(); });

    if (!success)
    {
        ChipLogError(NotSpecified, "Failed to start execution of button simulator!");
        return;
    }

    sButtonSimulatorInstance = std::move(buttonSimulator);
}

/**
 * Named pipe handler for simulating a latched switch movement.
 *
 * Usage example:
 *   echo '{"Name": "SimulateLatchPosition", "EndpointId": 3, "PositionId": 1}' > /tmp/chip_all_clusters_fifo_1146610
 *
 * JSON Arguments:
 *   - "Name": Must be "SimulateLatchPosition"
 *   - "EndpointId": ID of endpoint having a switch cluster
 *   - "PositionId": switch position for new CurrentPosition to set in switch cluster
 *
 * @param jsonValue - JSON payload from named pipe
 */

void HandleSimulateLatchPosition(Json::Value & jsonValue)
{
    bool hasEndpointId = HasNumericField(jsonValue, "EndpointId");
    bool hasPositionId = HasNumericField(jsonValue, "PositionId");

    if (!hasEndpointId || !hasPositionId)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId, PositionId in %s", inputJson.c_str());
        return;
    }

    EndpointId endpointId = static_cast<EndpointId>(jsonValue["EndpointId"].asUInt());
    uint8_t positionId    = static_cast<uint8_t>(jsonValue["PositionId"].asUInt());

    uint8_t numPositions = GetNumberOfSwitchPositions(endpointId);
    if (positionId >= numPositions)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Invalid PositionId (out of range) in %s", inputJson.c_str());
        return;
    }

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpointId);
    VerifyOrReturn(switchCluster != nullptr);

    uint8_t previousPositionId = switchCluster->GetCurrentPosition();
    if (positionId != previousPositionId)
    {
        CHIP_ERROR status = switchCluster->SetCurrentPosition(positionId);
        VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
        ChipLogDetail(NotSpecified, "The latching switch is moved to a new position: %u", static_cast<unsigned>(positionId));

        RETURN_SAFELY_IGNORED switchCluster->OnSwitchLatch(positionId);
    }
    else
    {
        ChipLogDetail(NotSpecified, "Not moving latching switch to a new position, already at %u",
                      static_cast<unsigned>(positionId));
    }
}

/**
 * Named pipe handler for simulating a Door Opening.
 *
 * Usage example:
 *   echo '{"Name":"SetRefrigeratorDoorStatus", "EndpointId": 1, "DoorOpen": 1}' > /tmp/chip_all_clusters_fifo_1146610
 *
 * JSON Arguments:
 *   - "Name": Must be "SetRefrigeratorDoorStatus"
 *   - "EndpointId": ID of endpoint
 *   - "DoorOpen": Status of the Door, open or closed.
 *
 * @param jsonValue - JSON payload from named pipe
 */
void SetRefrigeratorDoorStatusHandler(Json::Value & jsonValue)
{
    bool hasEndpointId = HasNumericField(jsonValue, "EndpointId");
    bool hasDoorStatus = HasNumericField(jsonValue, "DoorOpen");

    if (!hasEndpointId || !hasDoorStatus)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId, DoorOpen in %s", inputJson.c_str());
        return;
    }
    // values to update the door status
    EndpointId endpointId = static_cast<EndpointId>(jsonValue["EndpointId"].asUInt());
    bool doorStatus       = static_cast<bool>(jsonValue["DoorOpen"].asBool());
    ChipLogDetail(NotSpecified, "SetRefrigeratorDoorStatusHandler State -> %d.", doorStatus);
    if (!doorStatus)
    {
        RefrigeratorAlarmServer::Instance().SetMaskValue(endpointId, doorStatus);
        ChipLogDetail(NotSpecified, "Refrigeratoralarm status updated to :%d", doorStatus);
    }
    else
    {
        ChipLogDetail(NotSpecified, "Refrigeratoralarm status updated to :%d", doorStatus);
        RefrigeratorAlarmServer::Instance().SetMaskValue(endpointId, doorStatus);
        RefrigeratorAlarmServer::Instance().SetStateValue(endpointId, doorStatus);
    }
}

/**
 * Named pipe handler for simulating switch is idle
 *
 * Usage example:
 *   echo '{"Name": "SimulateSwitchIdle", "EndpointId": 3}' > /tmp/chip_all_clusters_fifo_1146610
 *
 * JSON Arguments:
 *   - "Name": Must be "SimulateSwitchIdle"
 *   - "EndpointId": ID of endpoint having a switch cluster
 *
 * @param jsonValue - JSON payload from named pipe
 */

void HandleSimulateSwitchIdle(Json::Value & jsonValue)
{
    bool hasEndpointId = HasNumericField(jsonValue, "EndpointId");

    if (!hasEndpointId)
    {
        std::string inputJson = jsonValue.toStyledString();
        ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId in %s", inputJson.c_str());
        return;
    }

    EndpointId endpointId = static_cast<EndpointId>(jsonValue["EndpointId"].asUInt());

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpointId);
    VerifyOrReturn(switchCluster != nullptr);

    LogErrorOnFailure(switchCluster->SetCurrentPosition(0));
}

} // namespace

AllClustersAppCommandHandler * AllClustersAppCommandHandler::FromJSON(const char * json)
{
    Json::Reader reader;
    Json::Value value;

    if (!reader.parse(json, value))
    {
        ChipLogError(NotSpecified,
                     "AllClusters App: Error parsing JSON with error %s:", reader.getFormattedErrorMessages().c_str());
        return nullptr;
    }

    if (value.empty() || !value.isObject())
    {
        ChipLogError(NotSpecified, "AllClusters App: Invalid JSON command received");
        return nullptr;
    }

    if (!value.isMember("Name") || !value["Name"].isString())
    {
        ChipLogError(NotSpecified, "AllClusters App: Invalid JSON command received: command name is missing");
        return nullptr;
    }

    return Platform::New<AllClustersAppCommandHandler>(std::move(value));
}

void AllClustersAppCommandHandler::HandleCommand(intptr_t context)
{
    auto * self      = reinterpret_cast<AllClustersAppCommandHandler *>(context);
    std::string name = self->mJsonValue["Name"].asString();

    VerifyOrExit(!self->mJsonValue.empty(), ChipLogError(NotSpecified, "Invalid JSON event command received"));

    if (name == "SoftwareFault")
    {
        self->OnSoftwareFaultEventHandler(Clusters::SoftwareDiagnostics::Events::SoftwareFault::Id);
    }
    else if (name == "HardwareFaultChange")
    {
        self->OnGeneralFaultEventHandler(Clusters::GeneralDiagnostics::Events::HardwareFaultChange::Id);
    }
    else if (name == "RadioFaultChange")
    {
        self->OnGeneralFaultEventHandler(Clusters::GeneralDiagnostics::Events::RadioFaultChange::Id);
    }
    else if (name == "NetworkFaultChange")
    {
        self->OnGeneralFaultEventHandler(Clusters::GeneralDiagnostics::Events::NetworkFaultChange::Id);
    }
    else if (name == "SwitchLatched")
    {
        uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
        self->OnSwitchLatchedHandler(newPosition);
    }
    else if (name == "InitialPress")
    {
        uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
        self->OnSwitchInitialPressedHandler(newPosition);
    }
    else if (name == "LongPress")
    {
        uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
        self->OnSwitchLongPressedHandler(newPosition);
    }
    else if (name == "ShortRelease")
    {
        uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
        self->OnSwitchShortReleasedHandler(previousPosition);
    }
    else if (name == "LongRelease")
    {
        uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
        self->OnSwitchLongReleasedHandler(previousPosition);
    }
    else if (name == "MultiPressOngoing")
    {
        uint8_t newPosition = static_cast<uint8_t>(self->mJsonValue["NewPosition"].asUInt());
        uint8_t count       = static_cast<uint8_t>(self->mJsonValue["CurrentNumberOfPressesCounted"].asUInt());
        self->OnSwitchMultiPressOngoingHandler(newPosition, count);
    }
    else if (name == "MultiPressComplete")
    {
        uint8_t previousPosition = static_cast<uint8_t>(self->mJsonValue["PreviousPosition"].asUInt());
        uint8_t count            = static_cast<uint8_t>(self->mJsonValue["TotalNumberOfPressesCounted"].asUInt());
        self->OnSwitchMultiPressCompleteHandler(previousPosition, count);
    }
    else if (name == "PowerOnReboot")
    {
        self->OnRebootSignalHandler(BootReasonType::kPowerOnReboot);
    }
    else if (name == "BrownOutReset")
    {
        self->OnRebootSignalHandler(BootReasonType::kBrownOutReset);
    }
    else if (name == "SoftwareWatchdogReset")
    {
        self->OnRebootSignalHandler(BootReasonType::kSoftwareWatchdogReset);
    }
    else if (name == "HardwareWatchdogReset")
    {
        self->OnRebootSignalHandler(BootReasonType::kHardwareWatchdogReset);
    }
    else if (name == "SoftwareUpdateCompleted")
    {
        self->OnRebootSignalHandler(BootReasonType::kSoftwareUpdateCompleted);
    }
    else if (name == "SoftwareReset")
    {
        self->OnRebootSignalHandler(BootReasonType::kSoftwareReset);
    }
    else if (name == "ModeChange")
    {
        using chip::app::DataModel::MakeNullable;
        std::string device   = self->mJsonValue["Device"].asString();
        std::string type     = self->mJsonValue["Type"].asString();
        Json::Value jsonMode = self->mJsonValue["Mode"];
        DataModel::Nullable<uint8_t> mode;
        if (!jsonMode.isNull())
        {
            mode = MakeNullable(static_cast<uint8_t>(jsonMode.asUInt()));
        }
        else
        {
            mode.SetNull();
        }
        self->OnModeChangeHandler(device, type, mode);
    }
    else if (name == "SetAirQuality")
    {
        Json::Value jsonAirQualityEnum = self->mJsonValue["NewValue"];

        if (jsonAirQualityEnum.isNull())
        {
            ChipLogError(NotSpecified, "The SetAirQuality command requires the NewValue key.");
        }
        else
        {
            self->OnAirQualityChange(static_cast<uint32_t>(jsonAirQualityEnum.asUInt()));
        }
    }
    else if (name == "OperationalStateChange")
    {
        std::string device    = self->mJsonValue["Device"].asString();
        std::string operation = self->mJsonValue["Operation"].asString();
        self->OnOperationalStateChange(device, operation, self->mJsonValue["Param"]);
    }
    else if (name == "SimulateLongPress")
    {
        HandleSimulateLongPress(self->mJsonValue);
    }
    else if (name == "SimulateMultiPress")
    {
        HandleSimulateMultiPress(self->mJsonValue);
    }
    else if (name == "SimulateLatchPosition")
    {
        HandleSimulateLatchPosition(self->mJsonValue);
    }
    else if (name == "SimulateSwitchIdle")
    {
        HandleSimulateSwitchIdle(self->mJsonValue);
    }
    else if (name == "SetOccupancy")
    {
        uint8_t occupancy     = static_cast<uint8_t>(self->mJsonValue["Occupancy"].asUInt());
        EndpointId endpointId = static_cast<EndpointId>(self->mJsonValue["EndpointId"].asUInt());

        if (1 == occupancy || 0 == occupancy)
        {
            self->HandleSetOccupancyChange(endpointId, occupancy);
        }
        else
        {
            ChipLogError(NotSpecified, "Invalid Occupancy state to set.");
        }
    }
    else if (name == "SetRefrigeratorDoorStatus")
    {
        SetRefrigeratorDoorStatusHandler(self->mJsonValue);
    }
    else if (name == "SimulateConfigurationVersionChange")
    {
        Clusters::BasicInformationCluster * cluster = Clusters::BasicInformation::GetClusterInstance();
        if (cluster == nullptr)
        {
            ChipLogError(NotSpecified, "No basic information cluster available. Invalid state.");
        }
        else
        {
            LogErrorOnFailure(cluster->IncreaseConfigurationVersion());
        }
    }
    else if (name == "SetSimulatedSoilMoisture")
    {
        EndpointId endpoint          = static_cast<EndpointId>(self->mJsonValue["EndpointId"].asUInt());
        Json::Value jsonSoilMoisture = self->mJsonValue["SoilMoistureValue"];
        DataModel::Nullable<Percent> soilMoistureMeasuredValue;

        if (endpoint != 1)
        {
            ChipLogError(NotSpecified, "Invalid EndpointId to set Soil Moisture value.");
            return;
        }

        if (jsonSoilMoisture.isNull())
        {
            soilMoistureMeasuredValue.SetNull();
        }
        else
        {
            soilMoistureMeasuredValue.SetNonNull(static_cast<uint8_t>(self->mJsonValue["SoilMoistureValue"].asUInt()));
        }

        self->OnSoilMoistureChange(endpoint, soilMoistureMeasuredValue);
    }
    else if (name == "UserIntentCommissioningStart")
    {
        TEMPORARY_RETURN_IGNORED Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow();
    }
    else if (name == "SetBooleanState")
    {
        bool hasEndpointId = HasNumericField(self->mJsonValue, "EndpointId");
        bool hasNewState   = self->mJsonValue.isMember("NewState");

        if (!hasEndpointId || !hasNewState)
        {
            std::string inputJson = self->mJsonValue.toStyledString();
            ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId, NewState in %s", inputJson.c_str());
            return;
        }

        if (!self->mJsonValue["EndpointId"].isUInt() || !self->mJsonValue["NewState"].isBool())
        {
            std::string inputJson = self->mJsonValue.toStyledString();
            ChipLogError(NotSpecified, "Invalid type for one of EndpointId, NewState in %s", inputJson.c_str());
            return;
        }

        auto endpointId = static_cast<chip::EndpointId>(self->mJsonValue["EndpointId"].asUInt());
        auto newState   = self->mJsonValue["NewState"].asBool();

        self->OnBooleanStateChangeHandler(endpointId, newState);
    }
    else if (name == "SetBooleanStateSensorFault")
    {
        bool hasEndpointId  = HasNumericField(self->mJsonValue, "EndpointId");
        bool hasSensorFault = HasNumericField(self->mJsonValue, "SensorFault");

        if (!hasEndpointId || !hasSensorFault)
        {
            std::string inputJson = self->mJsonValue.toStyledString();
            ChipLogError(NotSpecified, "Missing or invalid value for EndpointId or SensorFault in %s", inputJson.c_str());
            return;
        }

        auto endpointId  = static_cast<chip::EndpointId>(self->mJsonValue["EndpointId"].asUInt());
        auto sensorFault = static_cast<uint16_t>(self->mJsonValue["SensorFault"].asUInt());

        self->OnBooleanStateSensorFaultHandler(endpointId, sensorFault);
    }
    else if (name == "SetUnmounted")
    {
        uint8_t unmounted   = static_cast<uint8_t>(self->mJsonValue["Unmounted"].asUInt());
        EndpointId endpoint = static_cast<EndpointId>(self->mJsonValue["EndpointId"].asUInt());
        SmokeCoAlarmServer::Instance().SetInoperativeWhenUnmounted(true);
        if (1 == unmounted || 0 == unmounted)
        {
            VerifyOrReturn(SmokeCoAlarmServer::Instance().SetUnmountedState(endpoint, static_cast<bool>(unmounted)),
                           ChipLogError(NotSpecified, "Error setting unmounted state."));
        }
        else
        {
            ChipLogError(NotSpecified, "Invalid Unmounted state to set.");
        }
    }
    else
    {
        ChipLogError(NotSpecified, "Unhandled command '%s': this should never happen", name.c_str());
        VerifyOrDie(false && "Named pipe command not supported, see log above.");
    }

exit:
    Platform::Delete(self);
}

bool AllClustersAppCommandHandler::IsClusterPresentOnAnyEndpoint(ClusterId clusterId)
{
    EnabledEndpointsWithServerCluster enabledEndpoints(clusterId);

    return (enabledEndpoints.begin() != enabledEndpoints.end());
}

void AllClustersAppCommandHandler::OnRebootSignalHandler(BootReasonType bootReason)
{
    if (ConfigurationMgr().StoreBootReason(static_cast<uint32_t>(bootReason)) == CHIP_NO_ERROR)
    {
        Server::GetInstance().GenerateShutDownEvent();
        TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork(
            [](intptr_t) { TEMPORARY_RETURN_IGNORED PlatformMgr().StopEventLoopTask(); });
    }
    else
    {
        ChipLogError(NotSpecified, "Failed to store boot reason:%d", static_cast<uint32_t>(bootReason));
    }
}

void AllClustersAppCommandHandler::OnGeneralFaultEventHandler(uint32_t eventId)
{
    if (!IsClusterPresentOnAnyEndpoint(Clusters::GeneralDiagnostics::Id))
        return;

    if (eventId == Clusters::GeneralDiagnostics::Events::HardwareFaultChange::Id)
    {
        GeneralFaults<kMaxHardwareFaults> previous;
        GeneralFaults<kMaxHardwareFaults> current;

        using GeneralDiagnostics::HardwareFaultEnum;

        // On Linux Simulation, set following hardware faults statically.
        ReturnOnFailure(previous.add(to_underlying(HardwareFaultEnum::kRadio)));
        ReturnOnFailure(previous.add(to_underlying(HardwareFaultEnum::kPowerSource)));

        ReturnOnFailure(current.add(to_underlying(HardwareFaultEnum::kRadio)));
        ReturnOnFailure(current.add(to_underlying(HardwareFaultEnum::kSensor)));
        ReturnOnFailure(current.add(to_underlying(HardwareFaultEnum::kPowerSource)));
        ReturnOnFailure(current.add(to_underlying(HardwareFaultEnum::kUserInterfaceFault)));
        Clusters::GeneralDiagnostics::GlobalNotifyHardwareFaultsDetect(previous, current);
    }
    else if (eventId == Clusters::GeneralDiagnostics::Events::RadioFaultChange::Id)
    {
        GeneralFaults<kMaxRadioFaults> previous;
        GeneralFaults<kMaxRadioFaults> current;

        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kWiFiFault)));
        ReturnOnFailure(previous.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kThreadFault)));

        ReturnOnFailure(current.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kWiFiFault)));
        ReturnOnFailure(current.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kCellularFault)));
        ReturnOnFailure(current.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kThreadFault)));
        ReturnOnFailure(current.add(to_underlying(GeneralDiagnostics::RadioFaultEnum::kNFCFault)));
        Clusters::GeneralDiagnostics::GlobalNotifyRadioFaultsDetect(previous, current);
    }
    else if (eventId == Clusters::GeneralDiagnostics::Events::NetworkFaultChange::Id)
    {
        GeneralFaults<kMaxNetworkFaults> previous;
        GeneralFaults<kMaxNetworkFaults> current;

        // On Linux Simulation, set following radio faults statically.
        ReturnOnFailure(previous.add(to_underlying(Clusters::GeneralDiagnostics::NetworkFaultEnum::kHardwareFailure)));
        ReturnOnFailure(previous.add(to_underlying(Clusters::GeneralDiagnostics::NetworkFaultEnum::kNetworkJammed)));

        ReturnOnFailure(current.add(to_underlying(Clusters::GeneralDiagnostics::NetworkFaultEnum::kHardwareFailure)));
        ReturnOnFailure(current.add(to_underlying(Clusters::GeneralDiagnostics::NetworkFaultEnum::kNetworkJammed)));
        ReturnOnFailure(current.add(to_underlying(Clusters::GeneralDiagnostics::NetworkFaultEnum::kConnectionFailed)));
        Clusters::GeneralDiagnostics::GlobalNotifyNetworkFaultsDetect(previous, current);
    }
    else
    {
        ChipLogError(NotSpecified, "Unknow event ID:%d", eventId);
    }
}

void AllClustersAppCommandHandler::OnSoftwareFaultEventHandler(uint32_t eventId)
{
    VerifyOrReturn(eventId == Clusters::SoftwareDiagnostics::Events::SoftwareFault::Id,
                   ChipLogError(NotSpecified, "Unknown software fault event received"));

    if (!IsClusterPresentOnAnyEndpoint(Clusters::SoftwareDiagnostics::Id))
        return;

    Clusters::SoftwareDiagnostics::Events::SoftwareFault::Type softwareFault;
    char threadName[kMaxThreadNameLength + 1];

    softwareFault.id = static_cast<uint64_t>(getpid());
    Platform::CopyString(threadName, std::to_string(softwareFault.id).c_str());

    softwareFault.name.SetValue(CharSpan::fromCharString(threadName));

    std::time_t result = std::time(nullptr);
    // Using size of 50 as it is double the expected 25 characters "Www Mmm dd hh:mm:ss yyyy\n".
    char timeChar[50];
    if (std::strftime(timeChar, sizeof(timeChar), "%c", std::localtime(&result)))
    {
        softwareFault.faultRecording.SetValue(ByteSpan(Uint8::from_const_char(timeChar), strlen(timeChar)));
    }

    Clusters::SoftwareDiagnostics::SoftwareFaultListener::GlobalNotifySoftwareFaultDetect(softwareFault);
}

void AllClustersAppCommandHandler::OnSwitchLatchedHandler(uint8_t newPosition)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(newPosition);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The latching switch is moved to a new position:%d", newPosition);

    RETURN_SAFELY_IGNORED switchCluster->OnSwitchLatch(newPosition);
}

void AllClustersAppCommandHandler::OnSwitchInitialPressedHandler(uint8_t newPosition)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(newPosition);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The new position when the momentary switch starts to be pressed:%d", newPosition);

    RETURN_SAFELY_IGNORED switchCluster->OnInitialPress(newPosition);
}

void AllClustersAppCommandHandler::OnSwitchLongPressedHandler(uint8_t newPosition)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(newPosition);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed for a long time:%d", newPosition);

    RETURN_SAFELY_IGNORED switchCluster->OnLongPress(newPosition);

    // Long press to trigger smokeco self-test
    SmokeCoAlarmServer::Instance().RequestSelfTest(endpoint);
}

void AllClustersAppCommandHandler::OnSwitchShortReleasedHandler(uint8_t previousPosition)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(0);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The previous value of the CurrentPosition when the momentary switch has been released:%d",
                  previousPosition);

    RETURN_SAFELY_IGNORED switchCluster->OnShortRelease(previousPosition);
}

void AllClustersAppCommandHandler::OnSwitchLongReleasedHandler(uint8_t previousPosition)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(0);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
    ChipLogDetail(NotSpecified,
                  "The previous value of the CurrentPosition when the momentary switch has been released after having been "
                  "pressed for a long time:%d",
                  previousPosition);

    RETURN_SAFELY_IGNORED switchCluster->OnLongRelease(previousPosition);
}

void AllClustersAppCommandHandler::OnSwitchMultiPressOngoingHandler(uint8_t newPosition, uint8_t count)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(newPosition);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed in a multi-press sequence:%d",
                  newPosition);
    ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count);

    RETURN_SAFELY_IGNORED switchCluster->OnMultiPressOngoing(newPosition, count);
}

void AllClustersAppCommandHandler::OnSwitchMultiPressCompleteHandler(uint8_t previousPosition, uint8_t count)
{
    EndpointId endpoint = 1;

    auto switchCluster = Clusters::Switch::FindClusterOnEndpoint(endpoint);
    VerifyOrReturn(switchCluster != nullptr);

    CHIP_ERROR status = switchCluster->SetCurrentPosition(0);
    VerifyOrReturn(CHIP_NO_ERROR == status, ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute"));
    ChipLogDetail(NotSpecified, "The previous position when the momentary switch has been pressed in a multi-press sequence:%d",
                  previousPosition);
    ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count);

    RETURN_SAFELY_IGNORED switchCluster->OnMultiPressComplete(previousPosition, count);
}

void AllClustersAppCommandHandler::OnModeChangeHandler(std::string device, std::string type, DataModel::Nullable<uint8_t> mode)
{
    ModeBase::Instance * modeInstance = nullptr;
    if (device == "DishWasher")
    {
        modeInstance = DishwasherMode::Instance();
    }
    else if (device == "LaundryWasher")
    {
        modeInstance = LaundryWasherMode::Instance();
    }
    else if (device == "RvcClean")
    {
        modeInstance = RvcCleanMode::Instance();
    }
    else if (device == "RvcRun")
    {
        modeInstance = RvcRunMode::Instance();
    }
    else
    {
        ChipLogDetail(NotSpecified, "Invalid device type : %s", device.c_str());
        return;
    }

    if (type == "Current")
    {
        if (mode.IsNull())
        {
            ChipLogDetail(NotSpecified, "Invalid value : null");
            return;
        }
        modeInstance->UpdateCurrentMode(mode.Value());
    }
    else if (type == "StartUp")
    {
        modeInstance->UpdateStartUpMode(mode);
    }
    else if (type == "On")
    {
        modeInstance->UpdateOnMode(mode);
    }
    else if (type == "ToggleFailTransition")
    {
        modeInstance->ToggleFailTransition();
        return;
    }
    else
    {
        ChipLogDetail(NotSpecified, "Invalid mode type : %s", type.c_str());
        return;
    }
}

void AllClustersAppCommandHandler::OnOperationalStateChange(std::string device, std::string operation, Json::Value param)
{
    if (device == "Generic")
    {
        OnGenericOperationalStateChange(device, operation, param);
    }
    else if (device == "Oven")
    {
        OnOvenOperationalStateChange(device, operation, param);
    }
    else
    {
        ChipLogDetail(NotSpecified, "Invalid device type : %s", device.c_str());
        return;
    }
}

void AllClustersAppCommandHandler::OnGenericOperationalStateChange(std::string device, std::string operation, Json::Value param)
{
    OperationalState::Instance * operationalStateInstance                 = OperationalState::GetOperationalStateInstance();
    OperationalState::OperationalStateDelegate * operationalStateDelegate = OperationalState::GetOperationalStateDelegate();
    OperationalState::GenericOperationalError noError(to_underlying(OperationalState::ErrorStateEnum::kNoError));
    OperationalState::OperationalStateEnum state =
        static_cast<OperationalState::OperationalStateEnum>(operationalStateInstance->GetCurrentOperationalState());
    if (operation == "Start")
    {
        operationalStateDelegate->HandleStartStateCallback(noError);
    }
    else if (operation == "Resume")
    {
        operationalStateDelegate->HandleResumeStateCallback(noError);
    }
    else if (operation == "Pause")
    {
        operationalStateDelegate->HandlePauseStateCallback(noError);
    }
    else if (operation == "Stop" && state == OperationalState::OperationalStateEnum::kRunning)
    {
        operationalStateDelegate->HandleStopStateCallback(noError);
    }
    else if (operation == "OnFault")
    {
        uint8_t event_id = to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation);
        if (!param.isNull())
        {
            event_id = to_underlying(static_cast<OperationalState::ErrorStateEnum>(param.asUInt()));
        }

        OperationalState::GenericOperationalError err(event_id);
        operationalStateInstance->OnOperationalErrorDetected(err);
    }
    else
    {
        ChipLogDetail(NotSpecified, "Invalid operation : %s", operation.c_str());
        return;
    }
}

void AllClustersAppCommandHandler::OnOvenOperationalStateChange(std::string device, std::string operation, Json::Value param)
{
    OperationalState::Instance * operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance();
    if (operation == "Start" || operation == "Resume")
    {
        TEMPORARY_RETURN_IGNORED operationalStateInstance->SetOperationalState(
            to_underlying(OperationalState::OperationalStateEnum::kRunning));
    }
    else if (operation == "Pause")
    {
        TEMPORARY_RETURN_IGNORED operationalStateInstance->SetOperationalState(
            to_underlying(OperationalState::OperationalStateEnum::kPaused));
    }
    else if (operation == "Stop")
    {
        TEMPORARY_RETURN_IGNORED operationalStateInstance->SetOperationalState(
            to_underlying(OperationalState::OperationalStateEnum::kStopped));
    }
    else if (operation == "OnFault")
    {

        uint8_t event_id = to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation);
        if (!param.isNull())
        {
            event_id = to_underlying(static_cast<OperationalState::ErrorStateEnum>(param.asUInt()));
        }

        OperationalState::GenericOperationalError err(event_id);
        operationalStateInstance->OnOperationalErrorDetected(err);
    }
    else
    {
        ChipLogDetail(NotSpecified, "Invalid operation : %s", operation.c_str());
        return;
    }
}

void AllClustersAppCommandHandler::OnAirQualityChange(uint32_t aNewValue)
{
    AirQuality::Instance * airQualityInstance = AirQuality::GetInstance();
    Protocols::InteractionModel::Status status =
        airQualityInstance->UpdateAirQuality(static_cast<AirQuality::AirQualityEnum>(aNewValue));

    if (status != Protocols::InteractionModel::Status::Success)
    {
        ChipLogDetail(NotSpecified, "Invalid value: %u", aNewValue);
    }
}

void AllClustersAppCommandHandler::OnSoilMoistureChange(EndpointId endpointId, DataModel::Nullable<Percent> soilMoisture)
{
    if (soilMoisture.IsNull())
    {
        ChipLogDetail(NotSpecified, "Set SoilMoisture value to null");
    }
    else
    {
        ChipLogDetail(NotSpecified, "Set SoilMoisture value to %u", soilMoisture.Value());
    }

    TEMPORARY_RETURN_IGNORED SoilMeasurement::SetSoilMoistureMeasuredValue(soilMoisture);
}

void AllClustersAppCommandHandler::HandleSetOccupancyChange(EndpointId endpointId, uint8_t newOccupancyValue)
{
    chip::app::Clusters::OccupancySensingCluster * cluster = OccupancySensing::FindClusterOnEndpoint(endpointId);
    if (cluster == nullptr)
    {
        return;
    }
    cluster->SetOccupancy(newOccupancyValue == 1);
}

// TODO: Do not rely on global getters. Use a direct reference to a directly registered boolean state cluster.
// See https://github.com/project-chip/connectedhomeip/issues/43081
void AllClustersAppCommandHandler::OnBooleanStateChangeHandler(chip::EndpointId endpointId, bool newState)
{
    auto booleanState = BooleanState::FindClusterOnEndpoint(endpointId);
    if (booleanState != nullptr)
    {
        booleanState->SetStateValue(newState);
        ChipLogProgress(NotSpecified, "BooleanState changed to %s on endpoint %d", newState ? "true" : "false", endpointId);
    }
}

void AllClustersAppCommandHandler::OnBooleanStateSensorFaultHandler(chip::EndpointId endpointId, uint16_t sensorFault)
{
    BitMask<BooleanStateConfiguration::SensorFaultBitmap> fault(sensorFault);
    CHIP_ERROR err = BooleanStateConfiguration::EmitSensorFault(endpointId, fault);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(NotSpecified, "Failed to emit SensorFault on endpoint %d: %" CHIP_ERROR_FORMAT, endpointId, err.Format());
        return;
    }
    ChipLogProgress(NotSpecified, "SensorFault set to 0x%04x on endpoint %d", sensorFault, endpointId);
}

void AllClustersCommandDelegate::OnEventCommandReceived(const char * json)
{
    auto handler = AllClustersAppCommandHandler::FromJSON(json);
    if (nullptr == handler)
    {
        ChipLogError(NotSpecified, "AllClusters App: Unable to instantiate a command handler");
        return;
    }

    TEMPORARY_RETURN_IGNORED chip::DeviceLayer::PlatformMgr().ScheduleWork(AllClustersAppCommandHandler::HandleCommand,
                                                                           reinterpret_cast<intptr_t>(handler));
}
