/*
 *
 *    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::GetDefault(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));
}
