/**
 *
 *    Copyright (c) 2023 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 "boolean-state-configuration-server.h"

#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/AttributeAccessInterface.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/EventLogging.h>
#include <app/SafeAttributePersistenceProvider.h>
#include <app/data-model/Encode.h>
#include <app/util/attribute-storage.h>
#include <app/util/config.h>
#include <lib/core/CHIPError.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceConfig.h>

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::BooleanStateConfiguration::Attributes;
using chip::app::Clusters::BooleanStateConfiguration::Delegate;
using chip::Protocols::InteractionModel::Status;

static constexpr size_t kBooleanStateConfigurationDelegateTableSize =
    MATTER_DM_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

static_assert(kBooleanStateConfigurationDelegateTableSize <= kEmberInvalidEndpointIndex,
              "BooleanStateConfiguration Delegate table size error");

static constexpr uint8_t kMinSupportedSensitivityLevels = 2;
static constexpr uint8_t kMaxSupportedSensitivityLevels = 10;

static CHIP_ERROR StoreCurrentSensitivityLevel(EndpointId ep, uint8_t level);

namespace {
Delegate * gDelegateTable[kBooleanStateConfigurationDelegateTableSize] = { nullptr };

Delegate * GetDelegate(EndpointId endpoint)
{
    uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, BooleanStateConfiguration::Id,
                                                       MATTER_DM_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT);
    return (ep >= kBooleanStateConfigurationDelegateTableSize ? nullptr : gDelegateTable[ep]);
}

bool isDelegateNull(Delegate * delegate)
{
    if (delegate == nullptr)
    {
        return true;
    }
    return false;
}

class BooleanStateConfigAttrAccess : public AttributeAccessInterface
{
public:
    BooleanStateConfigAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), BooleanStateConfiguration::Id) {}

    CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override;
    CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;

private:
    CHIP_ERROR WriteCurrentSensitivityLevel(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder);
    CHIP_ERROR ReadCurrentSensitivityLevel(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder);
};

BooleanStateConfigAttrAccess gAttrAccess;

CHIP_ERROR BooleanStateConfigAttrAccess::WriteCurrentSensitivityLevel(const ConcreteDataAttributePath & aPath,
                                                                      AttributeValueDecoder & aDecoder)
{
    uint8_t curSenLevel;
    ReturnErrorOnFailure(aDecoder.Decode(curSenLevel));

    return StoreCurrentSensitivityLevel(aPath.mEndpointId, curSenLevel);
}

CHIP_ERROR BooleanStateConfigAttrAccess::ReadCurrentSensitivityLevel(const ConcreteReadAttributePath & aPath,
                                                                     AttributeValueEncoder & aEncoder)
{
    uint8_t senLevel;
    CHIP_ERROR err = GetSafeAttributePersistenceProvider()->ReadScalarValue(aPath, senLevel);
    if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
    {
        uint8_t supportedSensLevel;
        VerifyOrReturnError(Status::Success == SupportedSensitivityLevels::Get(aPath.mEndpointId, &supportedSensLevel),
                            CHIP_IM_GLOBAL_STATUS(Failure));
        VerifyOrReturnError(supportedSensLevel >= kMinSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(Failure));
        VerifyOrReturnError(supportedSensLevel <= kMaxSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(Failure));
        senLevel = static_cast<uint8_t>(supportedSensLevel - 1);
    }
    else if (err != CHIP_NO_ERROR)
    {
        return err;
    }

    ReturnErrorOnFailure(aEncoder.Encode(senLevel));

    return CHIP_NO_ERROR;
}

CHIP_ERROR BooleanStateConfigAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
    if (aPath.mClusterId != BooleanStateConfiguration::Id)
    {
        return CHIP_ERROR_INVALID_PATH_LIST;
    }

    switch (aPath.mAttributeId)
    {
    case CurrentSensitivityLevel::Id: {
        return ReadCurrentSensitivityLevel(aPath, aEncoder);
    }
    default: {
        break;
    }
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR BooleanStateConfigAttrAccess::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder)
{
    if (aPath.mClusterId != BooleanStateConfiguration::Id)
    {
        return CHIP_ERROR_INVALID_PATH_LIST;
    }

    switch (aPath.mAttributeId)
    {
    case CurrentSensitivityLevel::Id: {
        return WriteCurrentSensitivityLevel(aPath, aDecoder);
    }
    default: {
        break;
    }
    }

    return CHIP_NO_ERROR;
}
} // namespace

static bool emitAlarmsStateChangedEvent(EndpointId ep)
{
    if (!HasFeature(ep, BooleanStateConfiguration::Feature::kAudible) &&
        !HasFeature(ep, BooleanStateConfiguration::Feature::kVisual))
    {
        return false;
    }

    BooleanStateConfiguration::Events::AlarmsStateChanged::Type event;
    BitMask<BooleanStateConfiguration::AlarmModeBitmap> active;
    VerifyOrReturnValue(Status::Success == AlarmsActive::Get(ep, &active), false);
    event.alarmsActive = active;

    if (HasFeature(ep, BooleanStateConfiguration::Feature::kAlarmSuppress))
    {
        BitMask<BooleanStateConfiguration::AlarmModeBitmap> suppressed;
        VerifyOrReturnValue(Status::Success == AlarmsSuppressed::Get(ep, &suppressed), false);
        event.alarmsSuppressed.SetValue(suppressed);
    }

    EventNumber eventNumber;

    CHIP_ERROR error = LogEvent(event, ep, eventNumber);

    if (CHIP_NO_ERROR != error)
    {
        ChipLogError(Zcl, "Unable to emit AlarmsStateChanged event [ep=%d]", ep);
        return false;
    }

    ChipLogProgress(Zcl, "Emit AlarmsStateChanged event [ep=%d]", ep);
    return true;
}

static CHIP_ERROR emitSensorFaultEvent(EndpointId ep, BitMask<BooleanStateConfiguration::SensorFaultBitmap> fault)
{
    BooleanStateConfiguration::Events::SensorFault::Type event;
    EventNumber eventNumber;

    event.sensorFault = fault;

    CHIP_ERROR error = LogEvent(event, ep, eventNumber);

    if (CHIP_NO_ERROR != error)
    {
        ChipLogError(Zcl, "Unable to emit SensorFault event [ep=%d]", ep);
        return error;
    }

    ChipLogProgress(Zcl, "Emit SensorFault event [ep=%d]", ep);
    return CHIP_NO_ERROR;
}

static CHIP_ERROR StoreCurrentSensitivityLevel(EndpointId ep, uint8_t level)
{
    uint8_t supportedSensLevel;
    VerifyOrReturnError(Status::Success == SupportedSensitivityLevels::Get(ep, &supportedSensLevel),
                        CHIP_IM_GLOBAL_STATUS(Failure));
    VerifyOrReturnError(supportedSensLevel >= kMinSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(ConstraintError));
    VerifyOrReturnError(supportedSensLevel <= kMaxSupportedSensitivityLevels, CHIP_IM_GLOBAL_STATUS(ConstraintError));
    VerifyOrReturnError(level < supportedSensLevel, CHIP_IM_GLOBAL_STATUS(ConstraintError));

    ReturnErrorOnFailure(GetSafeAttributePersistenceProvider()->WriteScalarValue(
        ConcreteAttributePath(ep, BooleanStateConfiguration::Id, CurrentSensitivityLevel::Id), level));

    return CHIP_NO_ERROR;
}

namespace chip {
namespace app {
namespace Clusters {
namespace BooleanStateConfiguration {

void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate)
{
    uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, BooleanStateConfiguration::Id,
                                                       MATTER_DM_BOOLEAN_STATE_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT);
    // if endpoint is found
    if (ep < kBooleanStateConfigurationDelegateTableSize)
    {
        gDelegateTable[ep] = delegate;
    }
}

Delegate * GetDefaultDelegate(EndpointId endpoint)
{
    return GetDelegate(endpoint);
}

CHIP_ERROR SetAlarmsActive(EndpointId ep, BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarms)
{
    VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
                            HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
                        CHIP_IM_GLOBAL_STATUS(Failure));

    BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarmsEnabled;
    VerifyOrReturnError(Status::Success == AlarmsEnabled::Get(ep, &alarmsEnabled), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
    VerifyOrReturnError(alarmsEnabled.HasAll(alarms), CHIP_IM_GLOBAL_STATUS(Failure));

    VerifyOrReturnError(Status::Success == AlarmsActive::Set(ep, alarms), CHIP_IM_GLOBAL_STATUS(Failure));
    emitAlarmsStateChangedEvent(ep);

    return CHIP_NO_ERROR;
}

CHIP_ERROR SetAllEnabledAlarmsActive(EndpointId ep)
{
    VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
                            HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
                        CHIP_IM_GLOBAL_STATUS(Failure));

    BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarmsEnabled;
    VerifyOrReturnError(Status::Success == AlarmsEnabled::Get(ep, &alarmsEnabled), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));

    if (alarmsEnabled.HasAny())
    {
        VerifyOrReturnError(Status::Success == AlarmsActive::Set(ep, alarmsEnabled), CHIP_IM_GLOBAL_STATUS(Failure));
        emitAlarmsStateChangedEvent(ep);
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR ClearAllAlarms(EndpointId ep)
{
    BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarmsActive, alarmsSuppressed;
    bool emitEvent = false;

    VerifyOrReturnError(Status::Success == AlarmsActive::Get(ep, &alarmsActive), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
    VerifyOrReturnError(Status::Success == AlarmsSuppressed::Get(ep, &alarmsSuppressed),
                        CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));

    if (alarmsActive.HasAny())
    {
        alarmsActive.ClearAll();
        VerifyOrReturnError(Status::Success == AlarmsActive::Set(ep, alarmsActive), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
        emitEvent = true;
    }

    if (alarmsSuppressed.HasAny())
    {
        alarmsSuppressed.ClearAll();
        VerifyOrReturnError(Status::Success == AlarmsSuppressed::Set(ep, alarmsSuppressed),
                            CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute));
        emitEvent = true;
    }

    if (emitEvent)
    {
        emitAlarmsStateChangedEvent(ep);
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR SuppressAlarms(EndpointId ep, BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarm)
{
    CHIP_ERROR attribute_error = CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute);

    VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kAlarmSuppress),
                        CHIP_IM_GLOBAL_STATUS(UnsupportedCommand));
    VerifyOrReturnError(HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) ||
                            HasFeature(ep, BooleanStateConfiguration::Feature::kAudible),
                        CHIP_IM_GLOBAL_STATUS(UnsupportedCommand));

    BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarmsActive, alarmsSuppressed, alarmsSupported;

    VerifyOrReturnError(Status::Success == AlarmsSupported::Get(ep, &alarmsSupported), attribute_error);
    VerifyOrReturnError(alarmsSupported.HasAll(alarm), CHIP_IM_GLOBAL_STATUS(ConstraintError));

    VerifyOrReturnError(Status::Success == AlarmsActive::Get(ep, &alarmsActive), attribute_error);
    VerifyOrReturnError(alarmsActive.HasAll(alarm), CHIP_IM_GLOBAL_STATUS(InvalidInState));

    Delegate * delegate = GetDelegate(ep);
    if (!isDelegateNull(delegate))
    {
        delegate->HandleSuppressAlarm(alarm);
    }

    VerifyOrReturnError(Status::Success == AlarmsSuppressed::Get(ep, &alarmsSuppressed), attribute_error);
    alarmsSuppressed.Set(alarm);
    VerifyOrReturnError(Status::Success == AlarmsSuppressed::Set(ep, alarmsSuppressed), attribute_error);

    emitAlarmsStateChangedEvent(ep);

    return CHIP_NO_ERROR;
}

CHIP_ERROR SetCurrentSensitivityLevel(EndpointId ep, uint8_t level)
{
    return StoreCurrentSensitivityLevel(ep, level);
}

CHIP_ERROR EmitSensorFault(EndpointId ep, BitMask<BooleanStateConfiguration::SensorFaultBitmap> fault)
{
    ReturnErrorOnFailure(emitSensorFaultEvent(ep, fault));
    return CHIP_NO_ERROR;
}

} // namespace BooleanStateConfiguration
} // namespace Clusters
} // namespace app
} // namespace chip

bool emberAfBooleanStateConfigurationClusterSuppressAlarmCallback(
    CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
    const BooleanStateConfiguration::Commands::SuppressAlarm::DecodableType & commandData)
{
    const auto & alarms = commandData.alarmsToSuppress;
    CHIP_ERROR err      = BooleanStateConfiguration::SuppressAlarms(commandPath.mEndpointId, alarms);
    if (err == CHIP_NO_ERROR)
    {
        commandObj->AddStatus(commandPath, Status::Success);
    }
    else if (err == CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute))
    {
        commandObj->AddStatus(commandPath, Status::Failure);
    }
    else
    {
        commandObj->AddStatus(commandPath, StatusIB(err).mStatus);
    }

    return true;
}

bool emberAfBooleanStateConfigurationClusterEnableDisableAlarmCallback(
    CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
    const BooleanStateConfiguration::Commands::EnableDisableAlarm::DecodableType & commandData)
{
    const auto & alarms     = commandData.alarmsToEnableDisable;
    const auto & ep         = commandPath.mEndpointId;
    Optional<Status> status = Optional<Status>::Missing();

    if (!HasFeature(ep, BooleanStateConfiguration::Feature::kVisual) &&
        !HasFeature(ep, BooleanStateConfiguration::Feature::kAudible))
    {
        commandObj->AddStatus(commandPath, Status::UnsupportedCommand);
        return true;
    }

    BitMask<BooleanStateConfiguration::AlarmModeBitmap> alarmsActive, alarmsSuppressed, alarmsSupported, alarmsToDisable;
    Delegate * delegate = GetDelegate(ep);
    bool emit           = false;
    uint8_t rawAlarm    = static_cast<uint8_t>(~alarms.Raw() & 0x03); // 0x03 is the current max bitmap
    alarmsToDisable     = BitMask<BooleanStateConfiguration::AlarmModeBitmap>(rawAlarm);

    VerifyOrExit(Status::Success == AlarmsSupported::Get(ep, &alarmsSupported), status.Emplace(Status::Failure));
    VerifyOrExit(alarmsSupported.HasAll(alarms), status.Emplace(Status::ConstraintError));

    VerifyOrExit(Status::Success == AlarmsEnabled::Set(ep, alarms), status.Emplace(Status::Failure));

    if (!isDelegateNull(delegate))
    {
        delegate->HandleEnableDisableAlarms(alarms);
    }

    VerifyOrExit(Status::Success == AlarmsActive::Get(ep, &alarmsActive), status.Emplace(Status::Failure));
    if (alarmsActive.HasAny(alarmsToDisable))
    {
        alarmsActive.Clear(alarmsToDisable);
        VerifyOrExit(Status::Success == AlarmsActive::Set(ep, alarmsActive), status.Emplace(Status::Failure));
        emit = true;
    }

    VerifyOrExit(Status::Success == AlarmsSuppressed::Get(ep, &alarmsSuppressed), status.Emplace(Status::Failure));
    if (alarmsSuppressed.HasAny(alarmsToDisable))
    {
        alarmsSuppressed.Clear(alarmsToDisable);
        VerifyOrExit(Status::Success == AlarmsSuppressed::Set(ep, alarmsSuppressed), status.Emplace(Status::Failure));
        emit = true;
    }

    if (emit)
    {
        emitAlarmsStateChangedEvent(ep);
    }

exit:
    if (status.HasValue())
    {
        commandObj->AddStatus(commandPath, status.Value());
    }
    else
    {
        commandObj->AddStatus(commandPath, Status::Success);
    }

    return true;
}

void MatterBooleanStateConfigurationPluginServerInitCallback()
{
    registerAttributeAccessOverride(&gAttrAccess);
}
