/**
 *
 *    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/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/reporting/reporting.h>
#include <app/util/af-types.h>
#include <app/util/af.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <app/util/error-mapping.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;
using chip::Protocols::InteractionModel::Status;

#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, WindowCoveringFeature 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, WindowCoveringFeature::kLift) && HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift));
}

bool HasFeaturePaTilt(chip::EndpointId endpoint)
{
    return (HasFeature(endpoint, WindowCoveringFeature::kTilt) && HasFeature(endpoint, WindowCoveringFeature::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;
    }
}

Status 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 Status::Busy;
        }

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

    return Status::Success;
}

void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
{
    uint16_t ep = emberAfFindClusterServerEndpointIndex(endpoint, WindowCovering::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");

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, status);
        return true;
    }

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

    Delegate * delegate = GetDelegate(endpoint);
    if (delegate)
    {
        if (HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
        }

        if (HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Tilt));
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("WindowCovering has no delegate set for endpoint:%u", endpoint);
    }

    commandObj->AddStatus(commandPath, 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");

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, status);
        return true;
    }

    if (HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift))
    {
        Attributes::TargetPositionLiftPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX_CLOSED);
    }
    if (HasFeature(endpoint, WindowCoveringFeature::kPositionAwareTilt))
    {
        Attributes::TargetPositionTiltPercent100ths::Set(endpoint, WC_PERCENT100THS_MAX_CLOSED);
    }
    commandObj->AddStatus(commandPath, Status::Success);

    Delegate * delegate = GetDelegate(endpoint);
    if (delegate)
    {
        if (HasFeature(endpoint, WindowCoveringFeature::kPositionAwareLift))
        {
            LogErrorOnFailure(delegate->HandleMovement(WindowCoveringType::Lift));
        }

        if (HasFeature(endpoint, WindowCoveringFeature::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");

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, status);
        return true;
    }

    bool changeTarget = true;

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

    if (changeTarget)
    {
        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 CHIP_NO_ERROR == commandObj->AddStatus(commandPath, 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);

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, status);
        return true;
    }

    if (HasFeature(endpoint, WindowCoveringFeature::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);
        }
        commandObj->AddStatus(commandPath, Status::Success);
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA LF");
        commandObj->AddStatus(commandPath, 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);

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, 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);
            }
            commandObj->AddStatus(commandPath, Status::Success);
        }
        else
        {
            commandObj->AddStatus(commandPath, Status::ConstraintError);
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA LF");
        commandObj->AddStatus(commandPath, 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);

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, status);
        return true;
    }

    if (HasFeature(endpoint, WindowCoveringFeature::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);
        }
        commandObj->AddStatus(commandPath, Status::Success);
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA TL");
        commandObj->AddStatus(commandPath, 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);

    Status status = GetMotionLockStatus(endpoint);
    if (Status::Success != status)
    {
        emberAfWindowCoveringClusterPrint("Err device locked");
        commandObj->AddStatus(commandPath, 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);
            }
            commandObj->AddStatus(commandPath, Status::Success);
        }
        else
        {
            commandObj->AddStatus(commandPath, Status::ConstraintError);
        }
    }
    else
    {
        emberAfWindowCoveringClusterPrint("Err Device is not PA TL");
        commandObj->AddStatus(commandPath, 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() {}
