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

/****************************************************************************
 * @file
 * @brief Implementation for the Fan Control Server Cluster
 ***************************************************************************/

#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/clusters/fan-control-server/fan-control-server.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <protocols/interaction_model/StatusCode.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::FanControl;
using namespace chip::app::Clusters::FanControl::Attributes;

using Protocols::InteractionModel::Status;

namespace {

constexpr size_t kFanControlDelegateTableSize =
    MATTER_DM_FAN_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

static_assert(kFanControlDelegateTableSize <= kEmberInvalidEndpointIndex, "FanControl Delegate table size error");

Delegate * gDelegateTable[kFanControlDelegateTableSize] = { nullptr };

} // anonymous namespace

namespace chip {
namespace app {
namespace Clusters {
namespace FanControl {

Delegate * GetDelegate(EndpointId aEndpoint)
{
    uint16_t ep =
        emberAfGetClusterServerEndpointIndex(aEndpoint, FanControl::Id, MATTER_DM_FAN_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
    return (ep >= kFanControlDelegateTableSize ? nullptr : gDelegateTable[ep]);
}

void SetDefaultDelegate(EndpointId aEndpoint, Delegate * aDelegate)
{
    uint16_t ep =
        emberAfGetClusterServerEndpointIndex(aEndpoint, FanControl::Id, MATTER_DM_FAN_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT);
    // if endpoint is found
    if (ep < kFanControlDelegateTableSize)
    {
        gDelegateTable[ep] = aDelegate;
    }
}

} // namespace FanControl
} // namespace Clusters
} // namespace app
} // namespace chip

namespace {

// Indicates if the write operation is from the cluster server itself
bool gWriteFromClusterLogic = false;

Status SetFanModeToOff(EndpointId endpointId)
{
    FanModeEnum currentFanMode;
    Status status = FanMode::Get(endpointId, &currentFanMode);
    VerifyOrReturnError(Status::Success == status, status);

    if (currentFanMode != FanModeEnum::kOff)
    {
        status = FanMode::Set(endpointId, FanModeEnum::kOff);
    }

    return status;
}

bool HasFeature(EndpointId endpoint, Feature feature)
{
    bool success;
    uint32_t featureMap;
    success = (Attributes::FeatureMap::Get(endpoint, &featureMap) == Status::Success);

    return success ? ((featureMap & to_underlying(feature)) != 0) : false;
}

inline bool SupportsMultiSpeed(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kMultiSpeed);
}

inline bool SupportsAuto(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kAuto);
}

inline bool SupportsRocking(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kRocking);
}

inline bool SupportsWind(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kWind);
}

inline bool SupportsStep(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kStep);
}

inline bool SupportsAirflowDirection(EndpointId endpointId)
{
    return HasFeature(endpointId, Feature::kAirflowDirection);
}

} // anonymous namespace

// =============================================================================
// Pre-change callbacks for cluster attributes
// =============================================================================

using Status = Protocols::InteractionModel::Status;

Protocols::InteractionModel::Status
MatterFanControlClusterServerPreAttributeChangedCallback(const ConcreteAttributePath & attributePath,
                                                         EmberAfAttributeType attributeType, uint16_t size, uint8_t * value)
{
    Protocols::InteractionModel::Status res;

    switch (attributePath.mAttributeId)
    {
    case FanMode::Id: {
        if (*value == to_underlying(FanModeEnum::kOn))
        {
            FanMode::Set(attributePath.mEndpointId, FanModeEnum::kHigh);
            res = Status::WriteIgnored;
        }
        else if (*value == to_underlying(FanModeEnum::kSmart))
        {
            FanModeSequenceEnum fanModeSequence;
            Status status = FanModeSequence::Get(attributePath.mEndpointId, &fanModeSequence);
            VerifyOrReturnError(Status::Success == status, Status::Failure);

            if (SupportsAuto(attributePath.mEndpointId) &&
                ((fanModeSequence == FanModeSequenceEnum::kOffLowHighAuto) ||
                 (fanModeSequence == FanModeSequenceEnum::kOffLowMedHighAuto)))
            {
                FanMode::Set(attributePath.mEndpointId, FanModeEnum::kAuto);
            }
            else
            {
                FanMode::Set(attributePath.mEndpointId, FanModeEnum::kHigh);
            }
            res = Status::WriteIgnored;
        }
        else
        {
            res = Status::Success;
        }
        break;
    }
    case SpeedSetting::Id: {
        if (SupportsMultiSpeed(attributePath.mEndpointId))
        {
            // Check if the SpeedSetting is null.
            if (NumericAttributeTraits<uint8_t>::IsNullValue(*value))
            {

                if (gWriteFromClusterLogic)
                {
                    res                    = Status::Success;
                    gWriteFromClusterLogic = false;
                }
                else
                {
                    res = Status::WriteIgnored;
                }
            }
            else
            {
                uint8_t speedMax;
                Status status = SpeedMax::Get(attributePath.mEndpointId, &speedMax);
                VerifyOrReturnError(Status::Success == status, Status::ConstraintError);

                if (*value <= speedMax)
                {
                    res = Status::Success;
                }
                else
                {
                    res = Status::ConstraintError;
                }
            }
        }
        else
        {
            res = Status::UnsupportedAttribute;
        }
        break;
    }
    case PercentSetting::Id: {
        // Check if the PercentSetting is null.
        if (NumericAttributeTraits<Percent>::IsNullValue(*value))
        {
            if (gWriteFromClusterLogic)
            {
                res                    = Status::Success;
                gWriteFromClusterLogic = false;
            }
            else
            {
                res = Status::WriteIgnored;
            }
        }
        else
        {
            res = Status::Success;
        }
        break;
    }
    case RockSetting::Id: {
        if (SupportsRocking(attributePath.mEndpointId))
        {
            BitMask<RockBitmap> rockSupport;
            Status status = RockSupport::Get(attributePath.mEndpointId, &rockSupport);
            VerifyOrReturnError(Status::Success == status, Status::ConstraintError);
            auto rawRockSupport = rockSupport.Raw();
            if ((*value & rawRockSupport) == *value)
            {
                res = Status::Success;
            }
            else
            {
                res = Status::ConstraintError;
            }
        }
        else
        {
            res = Status::UnsupportedAttribute;
        }
        break;
    }
    case WindSetting::Id: {
        if (SupportsWind(attributePath.mEndpointId))
        {
            BitMask<WindBitmap> windSupport;
            Status status = WindSupport::Get(attributePath.mEndpointId, &windSupport);
            VerifyOrReturnError(Status::Success == status, Status::ConstraintError);
            auto rawWindSupport = windSupport.Raw();
            if ((*value & rawWindSupport) == *value)
            {
                res = Status::Success;
            }
            else
            {
                res = Status::ConstraintError;
            }
        }
        else
        {
            res = Status::UnsupportedAttribute;
        }
        break;
    }
    case AirflowDirection::Id: {
        if (SupportsAirflowDirection(attributePath.mEndpointId))
        {
            res = Status::Success;
        }
        else
        {
            res = Status::UnsupportedAttribute;
        }
        break;
    }
    default:
        res = Status::Success;
        break;
    }

    return res;
}

void MatterFanControlClusterServerAttributeChangedCallback(const app::ConcreteAttributePath & attributePath)
{
    switch (attributePath.mAttributeId)
    {
    case FanMode::Id: {
        FanModeEnum mode;
        Status status = FanMode::Get(attributePath.mEndpointId, &mode);
        VerifyOrReturn(Status::Success == status);

        // Setting the FanMode value to Off SHALL set the values of PercentSetting, PercentCurrent,
        // SpeedSetting, SpeedCurrent attributes to 0 (zero).
        if (mode == FanModeEnum::kOff)
        {
            status = PercentSetting::Set(attributePath.mEndpointId, 0);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to write PercentSetting with error: 0x%02x", to_underlying(status)));

            status = PercentCurrent::Set(attributePath.mEndpointId, 0);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to write PercentCurrent with error: 0x%02x", to_underlying(status)));

            if (SupportsMultiSpeed(attributePath.mEndpointId))
            {
                status = SpeedSetting::Set(attributePath.mEndpointId, 0);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to write SpeedSetting with error: 0x%02x", to_underlying(status)));

                status = SpeedCurrent::Set(attributePath.mEndpointId, 0);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to write SpeedCurrent with error: 0x%02x", to_underlying(status)));
            }
        }

        // Setting the attribute value to Auto SHALL set the values of PercentSetting, SpeedSetting (if present)
        // to null.
        if (mode == FanModeEnum::kAuto)
        {
            gWriteFromClusterLogic = true;
            status                 = PercentSetting::SetNull(attributePath.mEndpointId);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to write PercentSetting with error: 0x%02x", to_underlying(status)));

            if (SupportsMultiSpeed(attributePath.mEndpointId))
            {
                gWriteFromClusterLogic = true;
                status                 = SpeedSetting::SetNull(attributePath.mEndpointId);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to write SpeedSetting with error: 0x%02x", to_underlying(status)));
            }
        }
        break;
    }
    case PercentSetting::Id: {
        DataModel::Nullable<Percent> percentSetting;
        Status status = PercentSetting::Get(attributePath.mEndpointId, percentSetting);
        VerifyOrReturn(Status::Success == status && !percentSetting.IsNull());

        // If PercentSetting is set to 0, the server SHALL set the FanMode attribute value to Off.
        if (percentSetting.Value() == 0)
        {
            status = SetFanModeToOff(attributePath.mEndpointId);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to set FanMode to off with error: 0x%02x", to_underlying(status)));
        }

        if (SupportsMultiSpeed(attributePath.mEndpointId))
        {
            // Adjust SpeedSetting from a percent value change for PercentSetting
            // speed = ceil( SpeedMax * (percent * 0.01) )
            uint8_t speedMax;
            status = SpeedMax::Get(attributePath.mEndpointId, &speedMax);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to get SpeedMax with error: 0x%02x", to_underlying(status)));

            DataModel::Nullable<uint8_t> currentSpeedSetting;
            status = SpeedSetting::Get(attributePath.mEndpointId, currentSpeedSetting);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to get SpeedSetting with error: 0x%02x", to_underlying(status)));

            uint16_t percent = percentSetting.Value();
            // Plus 99 then integer divide by 100 instead of multiplying 0.01 to avoid floating point precision error
            uint8_t speedSetting = static_cast<uint8_t>((speedMax * percent + 99) / 100);

            if (currentSpeedSetting.IsNull() || speedSetting != currentSpeedSetting.Value())
            {
                status = SpeedSetting::Set(attributePath.mEndpointId, speedSetting);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to set SpeedSetting with error: 0x%02x", to_underlying(status)));
            }
        }
        break;
    }
    case SpeedSetting::Id: {
        if (SupportsMultiSpeed(attributePath.mEndpointId))
        {
            DataModel::Nullable<uint8_t> speedSetting;
            Status status = SpeedSetting::Get(attributePath.mEndpointId, speedSetting);
            VerifyOrReturn(Status::Success == status && !speedSetting.IsNull());

            // If SpeedSetting is set to 0, the server SHALL set the FanMode attribute value to Off.
            if (speedSetting.Value() == 0)
            {
                status = SetFanModeToOff(attributePath.mEndpointId);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to set FanMode to off with error: 0x%02x", to_underlying(status)));
            }

            // Adjust PercentSetting from a speed value change for SpeedSetting
            // percent = floor( speed/SpeedMax * 100 )
            uint8_t speedMax;
            status = SpeedMax::Get(attributePath.mEndpointId, &speedMax);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to get SpeedMax with error: 0x%02x", to_underlying(status)));

            DataModel::Nullable<Percent> currentPercentSetting;
            status = PercentSetting::Get(attributePath.mEndpointId, currentPercentSetting);
            VerifyOrReturn(Status::Success == status,
                           ChipLogError(Zcl, "Failed to get PercentSetting with error: 0x%02x", to_underlying(status)));

            float speed            = speedSetting.Value();
            Percent percentSetting = static_cast<Percent>(speed / speedMax * 100);

            if (currentPercentSetting.IsNull() || percentSetting != currentPercentSetting.Value())
            {
                status = PercentSetting::Set(attributePath.mEndpointId, percentSetting);
                VerifyOrReturn(Status::Success == status,
                               ChipLogError(Zcl, "Failed to set PercentSetting with error: 0x%02x", to_underlying(status)));
            }
        }
        break;
    }
    default:
        break;
    }
}

bool emberAfFanControlClusterStepCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                          const Commands::Step::DecodableType & commandData)
{
    Protocols::InteractionModel::Status status = Status::Success;

    ChipLogProgress(Zcl, "FanControl emberAfFanControlClusterStepCallback: Endpoint %u", commandPath.mEndpointId);

    if (!SupportsStep(commandPath.mEndpointId))
    {
        ChipLogProgress(Zcl, "FanControl does not support Step:%u", commandPath.mEndpointId);
        status = Status::UnsupportedCommand;
    }
    else
    {
        EndpointId endpoint         = commandPath.mEndpointId;
        StepDirectionEnum direction = commandData.direction;

        bool wrapValue      = commandData.wrap.ValueOr(false);
        bool lowestOffValue = commandData.lowestOff.ValueOr(false);

        Delegate * delegate = GetDelegate(endpoint);
        if (delegate)
        {
            status = delegate->HandleStep(direction, wrapValue, lowestOffValue);
        }
        else
        {
            ChipLogProgress(Zcl, "FanControl has no delegate set for endpoint:%u", endpoint);
            status = Status::Failure;
        }
    }

    commandObj->AddStatus(commandPath, status);
    return true;
}
