/**
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "window-covering-server.h"

#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/command-id.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/reporting/reporting.h>
#include <app/util/af-event.h>
#include <app/util/af-types.h>
#include <app/util/af.h>
#include <app/util/attribute-storage.h>
#include <lib/support/TypeTraits.h>
#include <string.h>

#ifdef EMBER_AF_PLUGIN_SCENES
#include <app/clusters/scenes/scenes.h>
#endif // EMBER_AF_PLUGIN_SCENES

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::WindowCovering;

#define CHECK_BOUNDS_INVALID(MIN, VAL, MAX) ((VAL < MIN) || (VAL > MAX))
#define CHECK_BOUNDS_VALID(MIN, VAL, MAX) (!CHECK_BOUNDS_INVALID(MIN, VAL, MAX))

#define FAKE_MOTION_DELAY_MS 5000

namespace {

constexpr size_t kWindowCoveringDelegateTableSize =
    EMBER_AF_WINDOW_COVERING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

Delegate * gDelegateTable[kWindowCoveringDelegateTableSize] = { nullptr };

Delegate * GetDelegate(EndpointId endpoint)
{
    uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, WindowCovering::Id);
    return ((ep == kInvalidEndpointId || ep >= EMBER_AF_WINDOW_COVERING_CLUSTER_SERVER_ENDPOINT_COUNT) ? nullptr
                                                                                                       : gDelegateTable[ep]);
}

/*
 * ConvertValue: Converts values from one range to another
 * Range In  -> from  inputLowValue to   inputHighValue
 * Range Out -> from outputLowValue to outputtHighValue
 */
uint16_t ConvertValue(uint16_t inputLowValue, uint16_t inputHighValue, uint16_t outputLowValue, uint16_t outputHighValue,
                      uint16_t value)
{
    uint16_t inputMin = inputLowValue, inputMax = inputHighValue, inputRange = UINT16_MAX;
    uint16_t outputMin = outputLowValue, outputMax = outputHighValue, outputRange = UINT16_MAX;

    if (inputLowValue > inputHighValue)
    {
        inputMin = inputHighValue;
        inputMax = inputLowValue;
    }

    if (outputLowValue > outputHighValue)
    {
        outputMin = outputHighValue;
        outputMax = outputLowValue;
    }

    inputRange  = static_cast<uint16_t>(inputMax - inputMin);
    outputRange = static_cast<uint16_t>(outputMax - outputMin);

    if (value < inputMin)
    {
        return outputMin;
    }

    if (value > inputMax)
    {
        return outputMax;
    }

    if (inputRange > 0)
    {
        return static_cast<uint16_t>(outputMin + ((outputRange * (value - inputMin) / inputRange)));
    }

    return outputMax;
}

Percent100ths ValueToPercent100ths(AbsoluteLimits limits, uint16_t absolute)
{
    return ConvertValue(limits.open, limits.closed, WC_PERCENT100THS_MIN_OPEN, WC_PERCENT100THS_MAX_CLOSED, absolute);
}
} // namespace

namespace chip {
namespace app {
namespace Clusters {
namespace WindowCovering {

bool HasFeature(chip::EndpointId endpoint, Feature feature)
{
    bool hasFeature     = false;
    uint32_t featureMap = 0;

    EmberAfStatus status = Attributes::FeatureMap::Get(endpoint, &featureMap);
    if (EMBER_ZCL_STATUS_SUCCESS == status)
    {
        hasFeature = (featureMap & chip::to_underlying(feature));
    }

    return hasFeature;
}

bool HasFeaturePaLift(chip::EndpointId endpoint)
{
    return (HasFeature(endpoint, Feature::kLift) && HasFeature(endpoint, Feature::kPositionAwareLift));
}

bool HasFeaturePaTilt(chip::EndpointId endpoint)
{
    return (HasFeature(endpoint, Feature::kTilt) && HasFeature(endpoint, Feature::kPositionAwareTilt));
}

void TypeSet(chip::EndpointId endpoint, Type type)
{
    Attributes::Type::Set(endpoint, type);
}

Type TypeGet(chip::EndpointId endpoint)
{
    Type value;
    Attributes::Type::Get(endpoint, &value);
    return value;
}

void ConfigStatusPrint(const chip::BitMask<ConfigStatus> & configStatus)
{
    emberAfWindowCoveringClusterPrint("ConfigStatus 0x%02X Operational=%u OnlineReserved=%u", configStatus.Raw(),
                                      configStatus.Has(ConfigStatus::kOperational),
                                      configStatus.Has(ConfigStatus::kOnlineReserved));

    emberAfWindowCoveringClusterPrint(
        "Lift(PA=%u Encoder=%u Reversed=%u) Tilt(PA=%u Encoder=%u)", configStatus.Has(ConfigStatus::kLiftPositionAware),
        configStatus.Has(ConfigStatus::kLiftEncoderControlled), configStatus.Has(ConfigStatus::kLiftMovementReversed),
        configStatus.Has(ConfigStatus::kTiltPositionAware), configStatus.Has(ConfigStatus::kTiltEncoderControlled));
}

void ConfigStatusSet(chip::EndpointId endpoint, const chip::BitMask<ConfigStatus> & configStatus)
{
    Attributes::ConfigStatus::Set(endpoint, configStatus);
}

chip::BitMask<ConfigStatus> ConfigStatusGet(chip::EndpointId endpoint)
{
    chip::BitMask<ConfigStatus> configStatus;
    Attributes::ConfigStatus::Get(endpoint, &configStatus);

    return configStatus;
}

void ConfigStatusUpdateFeatures(chip::EndpointId endpoint)
{
    chip::BitMask<ConfigStatus> configStatus = ConfigStatusGet(endpoint);

    configStatus.Set(ConfigStatus::kLiftPositionAware, HasFeaturePaLift(endpoint));
    configStatus.Set(ConfigStatus::kTiltPositionAware, HasFeaturePaTilt(endpoint));

    if (!HasFeaturePaLift(endpoint))
        configStatus.Clear(ConfigStatus::kLiftEncoderControlled);

    if (!HasFeaturePaTilt(endpoint))
        configStatus.Clear(ConfigStatus::kTiltEncoderControlled);

    ConfigStatusSet(endpoint, configStatus);
}

void OperationalStatusPrint(const chip::BitMask<OperationalStatus> & opStatus)
{
    emberAfWindowCoveringClusterPrint("OperationalStatus raw=0x%02X global=%u lift=%u tilt=%u", opStatus.Raw(),
                                      opStatus.GetField(OperationalStatus::kGlobal), opStatus.GetField(OperationalStatus::kLift),
                                      opStatus.GetField(OperationalStatus::kTilt));
}

chip::BitMask<OperationalStatus> OperationalStatusGet(chip::EndpointId endpoint)
{
    chip::BitMask<OperationalStatus> status;

    Attributes::OperationalStatus::Get(endpoint, &status);

    return status;
}

void OperationalStatusSet(chip::EndpointId endpoint, chip::BitMask<OperationalStatus> newStatus)
{
    chip::BitMask<OperationalStatus> prevStatus;
    Attributes::OperationalStatus::Get(endpoint, &prevStatus);

    // Filter changes
    if (newStatus != prevStatus)
    {
        OperationalStatusPrint(newStatus);
        Attributes::OperationalStatus::Set(endpoint, newStatus);
    }
}

void OperationalStateSet(chip::EndpointId endpoint, const chip::BitMask<OperationalStatus> field, OperationalState state)
{
    chip::BitMask<OperationalStatus> status;
    Attributes::OperationalStatus::Get(endpoint, &status);

    /* Filter only Lift or Tilt action since we cannot allow global reflecting a state alone */
    if ((OperationalStatus::kLift == field) || (OperationalStatus::kTilt == field))
    {
        status.SetField(field, static_cast<uint8_t>(state));
        status.SetField(OperationalStatus::kGlobal, static_cast<uint8_t>(state));

        /* Global Always follow Lift by priority or therefore fallback to Tilt */
        chip::BitMask<OperationalStatus> opGlobal =
            status.HasAny(OperationalStatus::kLift) ? OperationalStatus::kLift : OperationalStatus::kTilt;
        status.SetField(OperationalStatus::kGlobal, status.GetField(opGlobal));

        OperationalStatusSet(endpoint, status);
    }
}

OperationalState OperationalStateGet(chip::EndpointId endpoint, const chip::BitMask<OperationalStatus> field)
{
    chip::BitMask<OperationalStatus> status;

    Attributes::OperationalStatus::Get(endpoint, &status);

    return static_cast<OperationalState>(status.GetField(field));
}

void EndProductTypeSet(chip::EndpointId endpoint, EndProductType type)
{
    Attributes::EndProductType::Set(endpoint, type);
}

EndProductType EndProductTypeGet(chip::EndpointId endpoint)
{
    EndProductType value;
    Attributes::EndProductType::Get(endpoint, &value);

    return value;
}

void ModePrint(const chip::BitMask<Mode> & mode)
{
    emberAfWindowCoveringClusterPrint("Mode 0x%02X MotorDirReversed=%u LedFeedback=%u Maintenance=%u Calibration=%u", mode.Raw(),
                                      mode.Has(Mode::kMotorDirectionReversed), mode.Has(Mode::kLedFeedback),
                                      mode.Has(Mode::kMaintenanceMode), mode.Has(Mode::kCalibrationMode));
}

void ModeSet(chip::EndpointId endpoint, chip::BitMask<Mode> & newMode)
{
    chip::BitMask<ConfigStatus> newStatus;

    chip::BitMask<ConfigStatus> oldStatus = ConfigStatusGet(endpoint);
    chip::BitMask<Mode> oldMode           = ModeGet(endpoint);

    newStatus = oldStatus;

    // Attribute: ConfigStatus reflects the following current mode flags
    newStatus.Set(ConfigStatus::kOperational, !newMode.HasAny(Mode::kMaintenanceMode, Mode::kCalibrationMode));
    newStatus.Set(ConfigStatus::kLiftMovementReversed, newMode.Has(Mode::kMotorDirectionReversed));

    // Verify only one mode supported at once and maintenance lock goes over calibration
    if (newMode.HasAll(Mode::kMaintenanceMode, Mode::kCalibrationMode))
    {
        newMode.Clear(Mode::kCalibrationMode);
    }

    if (oldMode != newMode)
        Attributes::Mode::Set(endpoint, newMode);

    if (oldStatus != newStatus)
        ConfigStatusSet(endpoint, newStatus);
}

chip::BitMask<Mode> ModeGet(chip::EndpointId endpoint)
{
    chip::BitMask<Mode> mode;

    Attributes::Mode::Get(endpoint, &mode);
    return mode;
}

void SafetyStatusSet(chip::EndpointId endpoint, chip::BitMask<SafetyStatus> & newSafetyStatus)
{
    Attributes::SafetyStatus::Set(endpoint, newSafetyStatus);
}

chip::BitMask<SafetyStatus> SafetyStatusGet(chip::EndpointId endpoint)
{
    chip::BitMask<SafetyStatus> safetyStatus;

    Attributes::SafetyStatus::Get(endpoint, &safetyStatus);
    return safetyStatus;
}

LimitStatus CheckLimitState(uint16_t position, AbsoluteLimits limits)
{

    if (limits.open > limits.closed)
        return LimitStatus::Inverted;

    if (position == limits.open)
        return LimitStatus::IsUpOrOpen;

    if (position == limits.closed)
        return LimitStatus::IsDownOrClose;

    if ((limits.open > 0) && (position < limits.open))
        return LimitStatus::IsPastUpOrOpen;

    if ((limits.closed > 0) && (position > limits.closed))
        return LimitStatus::IsPastDownOrClose;

    return LimitStatus::Intermediate;
}

bool IsPercent100thsValid(Percent100ths percent100ths)
{
    if (CHECK_BOUNDS_VALID(WC_PERCENT100THS_MIN_OPEN, percent100ths, WC_PERCENT100THS_MAX_CLOSED))
        return true;

    return false;
}

bool IsPercent100thsValid(NPercent100ths percent100ths)
{
    if (!percent100ths.IsNull())
    {
        return IsPercent100thsValid(percent100ths.Value());
    }

    return true;
}

uint16_t Percent100thsToValue(AbsoluteLimits limits, Percent100ths relative)
{
    return ConvertValue(WC_PERCENT100THS_MIN_OPEN, WC_PERCENT100THS_MAX_CLOSED, limits.open, limits.closed, relative);
}

uint16_t LiftToPercent100ths(chip::EndpointId endpoint, uint16_t lift)
{
    uint16_t openLimit   = 0;
    uint16_t closedLimit = 0;
    Attributes::InstalledOpenLimitLift::Get(endpoint, &openLimit);
    Attributes::InstalledClosedLimitLift::Get(endpoint, &closedLimit);

    AbsoluteLimits limits = { .open = openLimit, .closed = closedLimit };
    return ValueToPercent100ths(limits, lift);
}

uint16_t Percent100thsToLift(chip::EndpointId endpoint, uint16_t percent100ths)
{
    uint16_t openLimit   = 0;
    uint16_t closedLimit = 0;
    Attributes::InstalledOpenLimitLift::Get(endpoint, &openLimit);
    Attributes::InstalledClosedLimitLift::Get(endpoint, &closedLimit);

    AbsoluteLimits limits = { .open = openLimit, .closed = closedLimit };
    return Percent100thsToValue(limits, percent100ths);
}

void LiftPositionSet(chip::EndpointId endpoint, NPercent100ths percent100ths)
{
    NPercent percent;
    NAbsolute rawpos;

    if (percent100ths.IsNull())
    {
        percent.SetNull();
        rawpos.SetNull();
        emberAfWindowCoveringClusterPrint("Lift[%u] Position Set to Null", endpoint);
    }
    else
    {
        percent.SetNonNull(static_cast<uint8_t>(percent100ths.Value() / 100));
        rawpos.SetNonNull(Percent100thsToLift(endpoint, percent100ths.Value()));
        emberAfWindowCoveringClusterPrint("Lift[%u] Position Set: %u", endpoint, percent100ths.Value());
    }
    Attributes::CurrentPositionLift::Set(endpoint, rawpos);
    Attributes::CurrentPositionLiftPercentage::Set(endpoint, percent);
    Attributes::CurrentPositionLiftPercent100ths::Set(endpoint, percent100ths);
}

uint16_t TiltToPercent100ths(chip::EndpointId endpoint, uint16_t tilt)
{
    uint16_t openLimit   = 0;
    uint16_t closedLimit = 0;
    Attributes::InstalledOpenLimitTilt::Get(endpoint, &openLimit);
    Attributes::InstalledClosedLimitTilt::Get(endpoint, &closedLimit);

    AbsoluteLimits limits = { .open = openLimit, .closed = closedLimit };

    return ValueToPercent100ths(limits, tilt);
}

uint16_t Percent100thsToTilt(chip::EndpointId endpoint, uint16_t percent100ths)
{
    uint16_t openLimit   = 0;
    uint16_t closedLimit = 0;
    Attributes::InstalledOpenLimitTilt::Get(endpoint, &openLimit);
    Attributes::InstalledClosedLimitTilt::Get(endpoint, &closedLimit);

    AbsoluteLimits limits = { .open = openLimit, .closed = closedLimit };

    return Percent100thsToValue(limits, percent100ths);
}

void TiltPositionSet(chip::EndpointId endpoint, NPercent100ths percent100ths)
{
    NPercent percent;
    NAbsolute rawpos;

    if (percent100ths.IsNull())
    {
        percent.SetNull();
        rawpos.SetNull();
        emberAfWindowCoveringClusterPrint("Tilt[%u] Position Set to Null", endpoint);
    }
    else
    {
        percent.SetNonNull(static_cast<uint8_t>(percent100ths.Value() / 100));
        rawpos.SetNonNull(Percent100thsToTilt(endpoint, percent100ths.Value()));
        emberAfWindowCoveringClusterPrint("Tilt[%u] Position Set: %u", endpoint, percent100ths.Value());
    }
    Attributes::CurrentPositionTilt::Set(endpoint, rawpos);
    Attributes::CurrentPositionTiltPercentage::Set(endpoint, percent);
    Attributes::CurrentPositionTiltPercent100ths::Set(endpoint, percent100ths);
}

OperationalState ComputeOperationalState(uint16_t target, uint16_t current)
{
    OperationalState opState = OperationalState::Stall;

    if (current != target)
    {
        opState = (current < target) ? OperationalState::MovingDownOrClose : OperationalState::MovingUpOrOpen;
    }
    return opState;
}

OperationalState ComputeOperationalState(NPercent100ths target, NPercent100ths current)
{
    if (!current.IsNull() && !target.IsNull())
    {
        return ComputeOperationalState(target.Value(), current.Value());
    }
    return OperationalState::Stall;
}

Percent100ths ComputePercent100thsStep(OperationalState direction, Percent100ths previous, Percent100ths delta)
{
    Percent100ths percent100ths = previous;

    switch (direction)
    {
    case OperationalState::MovingDownOrClose:
        if (percent100ths < (WC_PERCENT100THS_MAX_CLOSED - delta))
        {
            percent100ths = static_cast<Percent100ths>(percent100ths + delta);
        }
        else
        {
            percent100ths = WC_PERCENT100THS_MAX_CLOSED;
        }
        break;
    case OperationalState::MovingUpOrOpen:
        if (percent100ths > (WC_PERCENT100THS_MIN_OPEN + delta))
        {
            percent100ths = static_cast<Percent100ths>(percent100ths - delta);
        }
        else
        {
            percent100ths = WC_PERCENT100THS_MIN_OPEN;
        }
        break;
    default:
        // nothing to do we keep previous value, simple passthrought
        break;
    }

    if (percent100ths > WC_PERCENT100THS_MAX_CLOSED)
        return WC_PERCENT100THS_MAX_CLOSED;

    return percent100ths;
}

void PostAttributeChange(chip::EndpointId endpoint, chip::AttributeId attributeId)
{
    // all-cluster-app: simulation for the CI testing
    // otherwise it is defined for manufacturer specific implementation */
    BitMask<Mode> mode;
    BitMask<ConfigStatus> configStatus;
    NPercent100ths current, target;

    emberAfWindowCoveringClusterPrint("WC POST ATTRIBUTE=%u", (unsigned int) attributeId);

    OperationalState opLift = OperationalStateGet(endpoint, OperationalStatus::kLift);
    OperationalState opTilt = OperationalStateGet(endpoint, OperationalStatus::kTilt);

    switch (attributeId)
    {
    /* ============= Positions for Position Aware ============= */
    case Attributes::CurrentPositionLiftPercent100ths::Id:
        Attributes::TargetPositionLiftPercent100ths::Get(endpoint, target);
        Attributes::CurrentPositionLiftPercent100ths::Get(endpoint, current);
        if ((OperationalState::Stall != opLift) && (current == target))
        {
            emberAfWindowCoveringClusterPrint("Lift stop");
            OperationalStateSet(endpoint, OperationalStatus::kLift, OperationalState::Stall);
        }
        break;
    case Attributes::CurrentPositionTiltPercent100ths::Id:
        Attributes::TargetPositionTiltPercent100ths::Get(endpoint, target);
        Attributes::CurrentPositionTiltPercent100ths::Get(endpoint, current);
        if ((OperationalState::Stall != opTilt) && (current == target))
        {
            emberAfWindowCoveringClusterPrint("Tilt stop");
            OperationalStateSet(endpoint, OperationalStatus::kTilt, OperationalState::Stall);
        }
        break;
    /* For a device supporting Position Awareness : Changing the Target triggers motions on the real or simulated device */
    case Attributes::TargetPositionLiftPercent100ths::Id:
        Attributes::TargetPositionLiftPercent100ths::Get(endpoint, target);
        Attributes::CurrentPositionLiftPercent100ths::Get(endpoint, current);
        opLift = ComputeOperationalState(target, current);
        OperationalStateSet(endpoint, OperationalStatus::kLift, opLift);
        break;
    /* For a device supporting Position Awareness : Changing the Target triggers motions on the real or simulated device */
    case Attributes::TargetPositionTiltPercent100ths::Id:
        Attributes::TargetPositionTiltPercent100ths::Get(endpoint, target);
        Attributes::CurrentPositionTiltPercent100ths::Get(endpoint, current);
        opTilt = ComputeOperationalState(target, current);
        OperationalStateSet(endpoint, OperationalStatus::kTilt, opTilt);
        break;
    /* Mode change is either internal from the application or external from a write request */
    case Attributes::Mode::Id:
        mode = ModeGet(endpoint);
        ModePrint(mode);
        ModeSet(endpoint, mode); // refilter mode if needed
        break;
    case Attributes::ConfigStatus::Id:
        configStatus = ConfigStatusGet(endpoint);
        ConfigStatusPrint(configStatus);
        break;
    default:
        break;
    }
}

EmberAfStatus GetMotionLockStatus(chip::EndpointId endpoint)
{
    BitMask<Mode> mode                 = ModeGet(endpoint);
    BitMask<ConfigStatus> configStatus = ConfigStatusGet(endpoint);

    // Is the device locked?
    if (!configStatus.Has(ConfigStatus::kOperational))
    {
        if (mode.Has(Mode::kMaintenanceMode))
        {
            // Mainterance Mode
            return EMBER_ZCL_STATUS_BUSY;
        }

        if (mode.Has(Mode::kCalibrationMode))
        {
            // Calibration Mode
            return EMBER_ZCL_STATUS_FAILURE;
        }
    }

    return EMBER_ZCL_STATUS_SUCCESS;
}

void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
{
    uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, Channel::Id);

    // if endpoint is found and is not a dynamic endpoint
    if (ep != 0xFFFF && ep < EMBER_AF_WINDOW_COVERING_CLUSTER_SERVER_ENDPOINT_COUNT)
    {
        gDelegateTable[ep] = delegate;
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Failed to set WindowCovering delegate for endpoint:%u", endpoint);
    }
}

} // namespace WindowCovering
} // namespace Clusters
} // namespace app
} // namespace chip

//------------------------------------------------------------------------------
// Callbacks
//------------------------------------------------------------------------------

/**
 * @brief  Cluster UpOrOpen Command callback (from client)
 */
bool emberAfWindowCoveringClusterUpOrOpenCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                  const Commands::UpOrOpen::DecodableType & commandData)
{
    EndpointId endpoint = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("UpOrOpen command received");

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeature(endpoint, Feature::kPositionAwareLift))
    {
        Attributes::TargetPositionLiftPercent100ths::Set(endpoint, WC_PERCENT100THS_MIN_OPEN);
    }
    if (HasFeature(endpoint, Feature::kPositionAwareTilt))
    {
        Attributes::TargetPositionTiltPercent100ths::Set(endpoint, WC_PERCENT100THS_MIN_OPEN);
    }

    Delegate * delegate = GetDelegate(endpoint);
    if (delegate)
    {
        if (HasFeature(endpoint, Feature::kPositionAwareLift))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
        }
        else if (HasFeature(endpoint, Feature::kPositionAwareTilt))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt));
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
    }

    emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);

    return true;
}

/**
 * @brief  Cluster DownOrClose Command callback (from client)
 */
bool emberAfWindowCoveringClusterDownOrCloseCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                     const Commands::DownOrClose::DecodableType & commandData)
{
    EndpointId endpoint = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("DownOrClose command received");

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeature(endpoint, Feature::kPositionAwareLift))
    {
        Attributes::TargetPositionLiftPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX_CLOSED);
    }
    if (HasFeature(endpoint, Feature::kPositionAwareTilt))
    {
        Attributes::TargetPositionTiltPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX_CLOSED);
    }
    emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);

    Delegate * delegate = GetDelegate(endpoint);
    if (delegate)
    {
        if (HasFeature(endpoint, Feature::kPositionAwareLift))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
        }
        else if (HasFeature(endpoint, Feature::kPositionAwareTilt))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt));
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
    }

    return true;
}

/**
 * @brief  Cluster StopMotion Command callback (from client)
 */
bool emberAfWindowCoveringClusterStopMotionCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                    const Commands::StopMotion::DecodableType & fields)
{
    app::DataModel::Nullable<Percent100ths> current;
    chip::EndpointId endpoint = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("StopMotion command received");

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    Delegate * delegate = GetDelegate(endpoint);
    if (delegate)
    {
        LogErrorOnFailure(delegate->HandleStopMotion());
    }
    else
    {
        emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
    }

    if (HasFeaturePaLift(endpoint))
    {
        (void) Attributes::CurrentPositionLiftPercent100ths::Get(endpoint, current);
        (void) Attributes::TargetPositionLiftPercent100ths::Set(endpoint, current);
    }

    if (HasFeaturePaTilt(endpoint))
    {
        (void) Attributes::CurrentPositionTiltPercent100ths::Get(endpoint, current);
        (void) Attributes::TargetPositionTiltPercent100ths::Set(endpoint, current);
    }

    return EMBER_SUCCESS == emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
}

/**
 * @brief  Cluster GoToLiftValue Command callback (from client)
 */
bool emberAfWindowCoveringClusterGoToLiftValueCallback(app::CommandHandler * commandObj,
                                                       const app::ConcreteCommandPath & commandPath,
                                                       const Commands::GoToLiftValue::DecodableType & commandData)
{
    auto & liftValue = commandData.liftValue;

    EndpointId endpoint = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("GoToLiftValue %u command received", liftValue);

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeature(endpoint, Feature::kAbsolutePosition) && HasFeaturePaLift(endpoint))
    {
        Attributes::TargetPositionLiftPercent100ths::Set(endpoint, LiftToPercent100ths(endpoint, liftValue));
        Delegate * delegate = GetDelegate(endpoint);
        if (delegate)
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
        }
        else
        {
            emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
        }
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA LF");
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_FAILURE);
    }
    return true;
}

/**
 * @brief  Cluster GoToLiftPercentage Command callback (from client)
 */
bool emberAfWindowCoveringClusterGoToLiftPercentageCallback(app::CommandHandler * commandObj,
                                                            const app::ConcreteCommandPath & commandPath,
                                                            const Commands::GoToLiftPercentage::DecodableType & commandData)
{
    Percent100ths percent100ths = commandData.liftPercent100thsValue;
    EndpointId endpoint         = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("GoToLiftPercentage %u command received", percent100ths);

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeaturePaLift(endpoint))
    {
        if (IsPercent100thsValid(percent100ths))
        {
            Attributes::TargetPositionLiftPercent100ths::Set(endpoint, percent100ths);
            Delegate * delegate = GetDelegate(endpoint);
            if (delegate)
            {
                LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
            }
            else
            {
                emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
            }
            emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
        }
        else
        {
            emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA LF");
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_FAILURE);
    }
    return true;
}

/**
 * @brief  Cluster GoToTiltValue Command callback (from client)
 */
bool emberAfWindowCoveringClusterGoToTiltValueCallback(app::CommandHandler * commandObj,
                                                       const app::ConcreteCommandPath & commandPath,
                                                       const Commands::GoToTiltValue::DecodableType & commandData)
{
    auto & tiltValue = commandData.tiltValue;

    EndpointId endpoint = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("GoToTiltValue %u command received", tiltValue);

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeature(endpoint, Feature::kAbsolutePosition) && HasFeaturePaTilt(endpoint))
    {
        Attributes::TargetPositionTiltPercent100ths::Set(endpoint, TiltToPercent100ths(endpoint, tiltValue));
        Delegate * delegate = GetDelegate(endpoint);
        if (delegate)
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt));
        }
        else
        {
            emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
        }
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA TL");
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_FAILURE);
    }
    return true;
}

/**
 * @brief  Cluster GoToTiltPercentage Command callback (from client)
 */
bool emberAfWindowCoveringClusterGoToTiltPercentageCallback(app::CommandHandler * commandObj,
                                                            const app::ConcreteCommandPath & commandPath,
                                                            const Commands::GoToTiltPercentage::DecodableType & commandData)
{
    Percent100ths percent100ths = commandData.tiltPercent100thsValue;
    EndpointId endpoint         = commandPath.mEndpointId;

    emberAfWindowCoveringClusterPrint("GoToTiltPercentage %u command received", percent100ths);

    EmberAfStatus status = GetMotionLockStatus(endpoint);
    if (EMBER_ZCL_STATUS_SUCCESS != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        emberAfSendImmediateDefaultResponse(status);
        return true;
    }

    if (HasFeaturePaTilt(endpoint))
    {
        if (IsPercent100thsValid(percent100ths))
        {
            Attributes::TargetPositionTiltPercent100ths::Set(endpoint, percent100ths);
            Delegate * delegate = GetDelegate(endpoint);
            if (delegate)
            {
                LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt));
            }
            else
            {
                emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
            }
            emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
        }
        else
        {
            emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA TL");
        emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_FAILURE);
    }
    return true;
}

/**
 * @brief Cluster Attribute Changed Callback
 *
 * The method is implemented by default as a weak function and it takes care of updating
 * the server attribute values by calling the PostAttributeChange method. If the application overrides
 * this method, it needs to handle updating attributes (ideally by calling PostAttributeChange).
 *
 */
void __attribute__((weak))
MatterWindowCoveringClusterServerAttributeChangedCallback(const app::ConcreteAttributePath & attributePath)
{
    PostAttributeChange(attributePath.mEndpointId, attributePath.mAttributeId);
}

/**
 * @brief Cluster Plugin Init Callback
 */
void MatterWindowCoveringPluginServerInitCallback() {}
