Add the Pre-Attribute checking for laundry washer controls cluster (#28618)

* Add the PreAttribute checking for laundry washer controls cluster

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Restyled by clang-format

* Fix the warning in Darwin platform

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Move the Pre-Attribute checking from the delegate to cluster handler

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Restyled by clang-format

* * Remove the redundant checking for read-only attributes
* Not adding the API to get the size of the spin-speed list
* Add the nullable attribute checking

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Fix by follow review's comment
    - Replace a infinit for loop with a  while true loop
    - Use the meaning variables to access

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Restyled by clang-format

* Fix the tidy warning for "Build on Linux"

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

* Abort the program if delegate does not exist while writing the attribute

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>

---------

Signed-off-by: Chin-Ran Lo <chin-ran.lo@nxp.com>
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp
index 2eae63b..3917339 100644
--- a/examples/all-clusters-app/linux/main-common.cpp
+++ b/examples/all-clusters-app/linux/main-common.cpp
@@ -210,7 +210,7 @@
 using namespace chip::app::Clusters::LaundryWasherControls;
 void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint)
 {
-    LaundryWasherControlsServer::SetDefaultDelegate(1, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate());
+    LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate());
 }
 
 void emberAfLowPowerClusterInitCallback(EndpointId endpoint)
diff --git a/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp
index f7cb0cd..156d181 100644
--- a/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp
+++ b/src/app/clusters/laundry-washer-controls-server/laundry-washer-controls-server.cpp
@@ -192,3 +192,50 @@
     LaundryWasherControlsServer & laundryWasherControlsServer = LaundryWasherControlsServer::Instance();
     registerAttributeAccessOverride(&laundryWasherControlsServer);
 }
+
+Status MatterLaundryWasherControlsClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath,
+                                                                           EmberAfAttributeType attributeType, uint16_t size,
+                                                                           uint8_t * value)
+{
+    Delegate * delegate = GetDelegate(attributePath.mEndpointId);
+    VerifyOrDie((delegate != nullptr) && "Washer Controls implementation requires a registered delegate for validation.");
+    switch (attributePath.mAttributeId)
+    {
+    case Attributes::SpinSpeedCurrent::Id: {
+        if (NumericAttributeTraits<uint8_t>::IsNullValue(*value))
+        {
+            return Status::Success;
+        }
+        char buffer[LaundryWasherControlsServer::kMaxSpinSpeedLength];
+        MutableCharSpan spinSpeed(buffer);
+        uint8_t spinSpeedIndex = *value;
+        auto err               = delegate->GetSpinSpeedAtIndex(spinSpeedIndex, spinSpeed);
+        if (err == CHIP_NO_ERROR)
+        {
+            return Status::Success;
+        }
+        return Status::ConstraintError;
+    }
+    case Attributes::NumberOfRinses::Id: {
+        uint8_t supportedRinseIdx = 0;
+        while (true)
+        {
+            NumberOfRinsesEnum supportedRinse;
+            auto err = delegate->GetSupportedRinseAtIndex(supportedRinseIdx, supportedRinse);
+            if (err != CHIP_NO_ERROR)
+            {
+                // Can't find the attribute to be written in the supported list (CHIP_ERROR_PROVIDER_LIST_EXHAUSTED)
+                // Or can't get the correct supported list
+                return Status::InvalidInState;
+            }
+            if (supportedRinse == static_cast<NumberOfRinsesEnum>(*value))
+            {
+                // The written attribute is one of the supported item
+                return Status::Success;
+            }
+            supportedRinseIdx++;
+        }
+    }
+    }
+    return Status::Success;
+}
diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml
index 0e19b31..b6e8bf1 100644
--- a/src/app/common/templates/config-data.yaml
+++ b/src/app/common/templates/config-data.yaml
@@ -73,3 +73,4 @@
     - Mode Select
     - Fan Control
     - Thermostat
+    - Laundry Washer Controls