/**
 *
 *    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.
 */

/****************************************************************************
 * @file
 * @brief APIs and defines for the Door Lock Server
 *plugin.
 *******************************************************************************
 ******************************************************************************/

#pragma once

#include <app-common/zap-generated/af-structs.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/util/af.h>
#include <app/util/config.h>

#ifndef DOOR_LOCK_SERVER_ENDPOINT
#define DOOR_LOCK_SERVER_ENDPOINT 1
#endif

using chip::Optional;
using chip::app::Clusters::DoorLock::DlAlarmCode;
using chip::app::Clusters::DoorLock::DlCredentialRule;
using chip::app::Clusters::DoorLock::DlCredentialType;
using chip::app::Clusters::DoorLock::DlDataOperationType;
using chip::app::Clusters::DoorLock::DlDaysMaskMap;
using chip::app::Clusters::DoorLock::DlDoorState;
using chip::app::Clusters::DoorLock::DlLockDataType;
using chip::app::Clusters::DoorLock::DlLockOperationType;
using chip::app::Clusters::DoorLock::DlLockState;
using chip::app::Clusters::DoorLock::DlOperatingMode;
using chip::app::Clusters::DoorLock::DlOperationError;
using chip::app::Clusters::DoorLock::DlOperationSource;
using chip::app::Clusters::DoorLock::DlStatus;
using chip::app::Clusters::DoorLock::DlUserStatus;
using chip::app::Clusters::DoorLock::DlUserType;
using chip::app::Clusters::DoorLock::DoorLockFeature;
using chip::app::DataModel::List;
using chip::app::DataModel::Nullable;

using LockOpCredentials = chip::app::Clusters::DoorLock::Structs::DlCredential::Type;

typedef bool (*RemoteLockOpHandler)(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pinCode, DlOperationError & err);

static constexpr size_t DOOR_LOCK_MAX_USER_NAME_SIZE = 10; /**< Maximum size of the user name (in characters). */
static constexpr size_t DOOR_LOCK_USER_NAME_BUFFER_SIZE =
    DOOR_LOCK_MAX_USER_NAME_SIZE + 1; /**< Maximum size of the user name string (in bytes). */

struct EmberAfPluginDoorLockCredentialInfo;
struct EmberAfPluginDoorLockUserInfo;

struct EmberAfDoorLockEndpointContext
{
    chip::System::Clock::Timestamp lockoutEndTimestamp;
    int wrongCodeEntryAttempts;
};

/**
 * @brief Door Lock Server Plugin class.
 */
class DoorLockServer
{
public:
    static DoorLockServer & Instance();

    void InitServer(chip::EndpointId endpointId);

    /**
     * Updates the LockState attribute with new value and sends LockOperation event.
     *
     * @note Does not send an event of opSource is kRemote.
     *
     * @param endpointId ID of the endpoint to the lock state
     * @param newLockState new lock state
     * @param opSource source of the operation (will be used in the event).
     *
     * @return true on success, false on failure.
     */
    bool SetLockState(chip::EndpointId endpointId, DlLockState newLockState, DlOperationSource opSource);

    /**
     * Updates the LockState attribute with new value.
     *
     * @note Does not generate Lock Operation event
     *
     * @param endpointId ID of the endpoint to the lock state
     * @param newLockState new lock state
     *
     * @return true on success, false on failure.
     */
    bool SetLockState(chip::EndpointId endpointId, DlLockState newLockState);
    bool SetActuatorEnabled(chip::EndpointId endpointId, bool newActuatorState);
    bool SetDoorState(chip::EndpointId endpointId, DlDoorState newDoorState);

    bool SetLanguage(chip::EndpointId endpointId, chip::CharSpan newLanguage);
    bool SetAutoRelockTime(chip::EndpointId endpointId, uint32_t newAutoRelockTimeSec);
    bool SetSoundVolume(chip::EndpointId endpointId, uint8_t newSoundVolume);

    bool SetOneTouchLocking(chip::EndpointId endpointId, bool isEnabled);
    bool SetPrivacyModeButton(chip::EndpointId endpointId, bool isEnabled);

    bool TrackWrongCodeEntry(chip::EndpointId endpointId);

    bool GetAutoRelockTime(chip::EndpointId endpointId, uint32_t & autoRelockTime);
    bool GetNumberOfUserSupported(chip::EndpointId endpointId, uint16_t & numberOfUsersSupported);
    bool GetNumberOfPINCredentialsSupported(chip::EndpointId endpointId, uint16_t & numberOfPINCredentials);
    bool GetNumberOfRFIDCredentialsSupported(chip::EndpointId endpointId, uint16_t & numberOfRFIDCredentials);
    bool GetNumberOfWeekDaySchedulesPerUserSupported(chip::EndpointId endpointId, uint8_t & numberOfWeekDaySchedulesPerUser);
    bool GetNumberOfYearDaySchedulesPerUserSupported(chip::EndpointId endpointId, uint8_t & numberOfYearDaySchedulesPerUser);
    bool GetNumberOfCredentialsSupportedPerUser(chip::EndpointId endpointId, uint8_t & numberOfCredentialsSupportedPerUser);
    bool GetNumberOfHolidaySchedulesSupported(chip::EndpointId endpointId, uint8_t & numberOfHolidaySchedules);

    bool SendLockAlarmEvent(chip::EndpointId endpointId, DlAlarmCode alarmCode);

    chip::BitFlags<DoorLockFeature> GetFeatures(chip::EndpointId endpointId);

    inline bool SupportsPIN(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kPINCredentials); }

    inline bool SupportsRFID(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kRFIDCredentials); }

    inline bool SupportsFingers(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId).Has(DoorLockFeature::kFingerCredentials);
    }

    inline bool SupportsFace(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(DoorLockFeature::kFaceCredentials); }

    inline bool SupportsWeekDaySchedules(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId).Has(DoorLockFeature::kWeekDaySchedules);
    }

    inline bool SupportsYearDaySchedules(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId).Has(DoorLockFeature::kYearDaySchedules);
    }

    inline bool SupportsHolidaySchedules(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId).Has(DoorLockFeature::kHolidaySchedules);
    }

    inline bool SupportsAnyCredential(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId)
            .HasAny(DoorLockFeature::kPINCredentials, DoorLockFeature::kRFIDCredentials, DoorLockFeature::kFingerCredentials,
                    DoorLockFeature::kFaceCredentials);
    }

    inline bool SupportsCredentialsOTA(chip::EndpointId endpointId)
    {
        return GetFeatures(endpointId).Has(DoorLockFeature::kCredentialsOTA);
    }

    inline bool SupportsUSR(chip::EndpointId endpointId)
    {
        // appclusters, 5.2.2: USR feature has conformance [PIN | RID | FGP | FACE]
        return GetFeatures(endpointId).Has(DoorLockFeature::kUsersManagement) && SupportsAnyCredential(endpointId);
    }

    bool OnFabricRemoved(chip::EndpointId endpointId, chip::FabricIndex fabricIndex);

private:
    chip::FabricIndex getFabricIndex(const chip::app::CommandHandler * commandObj);
    chip::NodeId getNodeId(const chip::app::CommandHandler * commandObj);

    bool userIndexValid(chip::EndpointId endpointId, uint16_t userIndex);
    bool userIndexValid(chip::EndpointId endpointId, uint16_t userIndex, uint16_t & maxNumberOfUser);
    bool userExists(chip::EndpointId endpointId, uint16_t userIndex);

    bool credentialIndexValid(chip::EndpointId endpointId, DlCredentialType type, uint16_t credentialIndex);
    bool credentialIndexValid(chip::EndpointId endpointId, DlCredentialType type, uint16_t credentialIndex,
                              uint16_t & maxNumberOfCredentials);
    DlStatus credentialLengthWithinRange(chip::EndpointId endpointId, DlCredentialType type, const chip::ByteSpan & credentialData);
    bool getMaxNumberOfCredentials(chip::EndpointId endpointId, DlCredentialType credentialType, uint16_t & maxNumberOfCredentials);

    bool findOccupiedUserSlot(chip::EndpointId endpointId, uint16_t startIndex, uint16_t & userIndex);

    bool findUnoccupiedUserSlot(chip::EndpointId endpointId, uint16_t & userIndex);
    bool findUnoccupiedUserSlot(chip::EndpointId endpointId, uint16_t startIndex, uint16_t & userIndex);

    bool findOccupiedCredentialSlot(chip::EndpointId endpointId, DlCredentialType credentialType, uint16_t startIndex,
                                    uint16_t & credentialIndex);
    bool findUnoccupiedCredentialSlot(chip::EndpointId endpointId, DlCredentialType credentialType, uint16_t startIndex,
                                      uint16_t & credentialIndex);

    bool findUserIndexByCredential(chip::EndpointId endpointId, DlCredentialType credentialType, uint16_t credentialIndex,
                                   uint16_t & userIndex);

    bool findUserIndexByCredential(chip::EndpointId endpointId, DlCredentialType credentialType, chip::ByteSpan credentialData,
                                   uint16_t & userIndex, uint16_t & credentialIndex, EmberAfPluginDoorLockUserInfo & userInfo);

    EmberAfStatus createUser(chip::EndpointId endpointId, chip::FabricIndex creatorFabricIdx, chip::NodeId sourceNodeId,
                             uint16_t userIndex, const Nullable<chip::CharSpan> & userName, const Nullable<uint32_t> & userUniqueId,
                             const Nullable<DlUserStatus> & userStatus, const Nullable<DlUserType> & userType,
                             const Nullable<DlCredentialRule> & credentialRule,
                             const Nullable<DlCredential> & credential = Nullable<DlCredential>());
    EmberAfStatus modifyUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId,
                             uint16_t userIndex, const Nullable<chip::CharSpan> & userName, const Nullable<uint32_t> & userUniqueId,
                             const Nullable<DlUserStatus> & userStatus, const Nullable<DlUserType> & userType,
                             const Nullable<DlCredentialRule> & credentialRule);
    EmberAfStatus clearUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricId, chip::NodeId sourceNodeId,
                            uint16_t userIndex, bool sendUserChangeEvent);
    EmberAfStatus clearUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricId, chip::NodeId sourceNodeId,
                            uint16_t userIndex, const EmberAfPluginDoorLockUserInfo & user, bool sendUserChangeEvent);

    bool clearFabricFromUsers(chip::EndpointId endpointId, chip::FabricIndex fabricIndex);

    DlStatus createNewCredentialAndUser(chip::EndpointId endpointId, chip::FabricIndex creatorFabricIdx, chip::NodeId sourceNodeId,
                                        const Nullable<DlUserStatus> & userStatus, const Nullable<DlUserType> & userType,
                                        const DlCredential & credential, const chip::ByteSpan & credentialData,
                                        uint16_t & createdUserIndex);
    DlStatus createNewCredentialAndAddItToUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIdx, uint16_t userIndex,
                                               const DlCredential & credential, const chip::ByteSpan & credentialData);

    DlStatus addCredentialToUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIdx, uint16_t userIndex,
                                 const DlCredential & credential);
    DlStatus modifyCredentialForUser(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIdx, uint16_t userIndex,
                                     const DlCredential & credential);

    DlStatus createCredential(chip::EndpointId endpointId, chip::FabricIndex creatorFabricIdx, chip::NodeId sourceNodeId,
                              uint16_t credentialIndex, DlCredentialType credentialType,
                              const EmberAfPluginDoorLockCredentialInfo & existingCredential, const chip::ByteSpan & credentialData,
                              Nullable<uint16_t> userIndex, const Nullable<DlUserStatus> & userStatus,
                              Nullable<DlUserType> userType, uint16_t & createdUserIndex);
    DlStatus modifyProgrammingPIN(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId,
                                  uint16_t credentialIndex, DlCredentialType credentialType,
                                  const EmberAfPluginDoorLockCredentialInfo & existingCredential,
                                  const chip::ByteSpan & credentialData);
    DlStatus modifyCredential(chip::EndpointId endpointId, chip::FabricIndex modifierFabricIndex, chip::NodeId sourceNodeId,
                              uint16_t credentialIndex, DlCredentialType credentialType,
                              const EmberAfPluginDoorLockCredentialInfo & existingCredential, const chip::ByteSpan & credentialData,
                              uint16_t userIndex, const Nullable<DlUserStatus> & userStatus, Nullable<DlUserType> userType);

    EmberAfStatus clearCredential(chip::EndpointId endpointId, chip::FabricIndex modifier, chip::NodeId sourceNodeId,
                                  DlCredentialType credentialType, uint16_t credentialIndex, bool sendUserChangeEvent);
    EmberAfStatus clearCredentials(chip::EndpointId endpointId, chip::FabricIndex modifier, chip::NodeId sourceNodeId);
    EmberAfStatus clearCredentials(chip::EndpointId endpointId, chip::FabricIndex modifier, chip::NodeId sourceNodeId,
                                   DlCredentialType credentialType);

    bool clearFabricFromCredentials(chip::EndpointId endpointId, DlCredentialType credentialType, chip::FabricIndex fabricToRemove);
    bool clearFabricFromCredentials(chip::EndpointId endpointId, chip::FabricIndex fabricToRemove);

    void sendSetCredentialResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                   DlStatus status, uint16_t userIndex, uint16_t nextCredentialIndex);

    // TODO: Maybe use CHIP_APPLICATION_ERROR instead of boolean in class methods?
    // OPTIMIZE: there are a lot of methods such as this that could be made static which could help reduce the stack footprint
    // in case of multiple lock endpoints
    bool credentialTypeSupported(chip::EndpointId endpointId, DlCredentialType type);

    bool weekDayIndexValid(chip::EndpointId endpointId, uint8_t weekDayIndex);

    DlStatus clearWeekDaySchedule(chip::EndpointId endpointId, uint16_t userIndex, uint8_t weekDayIndex);
    DlStatus clearWeekDaySchedules(chip::EndpointId endpointId, uint16_t userIndex);
    DlStatus clearSchedules(chip::EndpointId endpointId, uint16_t userIndex);

    void sendGetWeekDayScheduleResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                        uint8_t weekdayIndex, uint16_t userIndex, DlStatus status,
                                        DlDaysMaskMap daysMask = DlDaysMaskMap(0), uint8_t startHour = 0, uint8_t startMinute = 0,
                                        uint8_t endHour = 0, uint8_t endMinute = 0);

    bool yearDayIndexValid(chip::EndpointId endpointId, uint8_t yearDayIndex);

    DlStatus clearYearDaySchedule(chip::EndpointId endpointId, uint16_t userIndex, uint8_t weekDayIndex);
    DlStatus clearYearDaySchedules(chip::EndpointId endpointId, uint16_t userIndex);

    void sendGetYearDayScheduleResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                        uint8_t yearDayIndex, uint16_t userIndex, DlStatus status, uint32_t localStartTime = 0,
                                        uint32_t localEndTime = 0);

    bool holidayIndexValid(chip::EndpointId endpointId, uint8_t holidayIndex);

    DlStatus clearHolidaySchedule(chip::EndpointId endpointId, uint8_t holidayIndex);
    DlStatus clearHolidaySchedules(chip::EndpointId endpointId);

    void sendHolidayScheduleResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                     uint8_t holidayIndex, DlStatus status, uint32_t localStartTime = 0, uint32_t localEndTime = 0,
                                     DlOperatingMode operatingMode = DlOperatingMode::kNormal);

    bool sendRemoteLockUserChange(chip::EndpointId endpointId, DlLockDataType dataType, DlDataOperationType operation,
                                  chip::NodeId nodeId, chip::FabricIndex fabricIndex, uint16_t userIndex = 0,
                                  uint16_t dataIndex = 0);

    DlLockDataType credentialTypeToLockDataType(DlCredentialType credentialType);

    bool isUserScheduleRestricted(chip::EndpointId endpointId, const EmberAfPluginDoorLockUserInfo & user);

    void setUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                               const chip::app::Clusters::DoorLock::Commands::SetUser::DecodableType & commandData);

    void getUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                               uint16_t userIndex);

    void clearUserCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                 uint16_t userIndex);

    void setCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                     const chip::app::Clusters::DoorLock::Commands::SetCredential::DecodableType & commandData);

    void getCredentialStatusCommandHandler(chip::app::CommandHandler * commandObj,
                                           const chip::app::ConcreteCommandPath & commandPath, DlCredentialType credentialType,
                                           uint16_t credentialIndex);

    void sendGetCredentialResponse(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                   DlCredentialType credentialType, uint16_t credentialIndex, uint16_t userIndexWithCredential,
                                   EmberAfPluginDoorLockCredentialInfo * credentialInfo, bool credentialExists);

    void clearCredentialCommandHandler(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                       const chip::app::Clusters::DoorLock::Commands::ClearCredential::DecodableType & commandData);

    void setWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
                                          uint16_t userIndex, const chip::BitMask<DlDaysMaskMap> & daysMask, uint8_t startHour,
                                          uint8_t startMinute, uint8_t endHour, uint8_t endMinute);

    void getWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
                                          uint16_t userIndex);

    void clearWeekDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                            const chip::app::ConcreteCommandPath & commandPath, uint8_t weekDayIndex,
                                            uint16_t userIndex);

    void setYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
                                          uint16_t userIndex, uint32_t localStartTime, uint32_t localEndTime);
    void getYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
                                          uint16_t userIndex);
    void clearYearDayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                            const chip::app::ConcreteCommandPath & commandPath, uint8_t yearDayIndex,
                                            uint16_t userIndex);

    void setHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex,
                                          uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode);

    void getHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex);

    void clearHolidayScheduleCommandHandler(chip::app::CommandHandler * commandObj,
                                            const chip::app::ConcreteCommandPath & commandPath, uint8_t holidayIndex);

    bool RemoteOperationEnabled(chip::EndpointId endpointId) const;

    EmberAfDoorLockEndpointContext * getContext(chip::EndpointId endpointId);

    bool engageLockout(chip::EndpointId endpointId);

    static CHIP_ERROR sendClusterResponse(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath, EmberAfStatus status);

    /**
     * @brief Common handler for LockDoor, UnlockDoor, UnlockWithTimeout commands
     *
     * @param commandObj    original command context
     * @param commandPath   original command path
     * @param opType        remote operation type (lock, unlock)
     * @param opHandler     plugin handler for specified command
     * @param pinCode       pin code passed by client
     * @return true         if locking/unlocking was successful
     * @return false        if error happened during lock/unlock
     */
    bool HandleRemoteLockOperation(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
                                   DlLockOperationType opType, RemoteLockOpHandler opHandler,
                                   const chip::Optional<chip::ByteSpan> & pinCode);

    /**
     * @brief Send LockOperation event if opSuccess is true, otherwise send LockOperationError with given opErr code
     *
     * @param endpointId    endpoint where DoorLockServer is running
     * @param opType        lock operation type (lock, unlock, etc)
     * @param opSource      operation source (remote, keypad, auto, etc)
     * @param opErr         operation error code (if opSuccess == false)
     * @param userId        user id
     * @param fabricIdx     fabric index
     * @param nodeId        node id
     * @param credList      list of credentials used in lock operation (can be NULL if no credentials were used)
     * @param credListSize  size of credentials list (if 0, then no credentials were used)
     * @param opSuccess     flags if operation was successful or not
     */
    void SendLockOperationEvent(chip::EndpointId endpointId, DlLockOperationType opType, DlOperationSource opSource,
                                DlOperationError opErr, const Nullable<uint16_t> & userId,
                                const Nullable<chip::FabricIndex> & fabricIdx, const Nullable<chip::NodeId> & nodeId,
                                LockOpCredentials * credList, size_t credListSize, bool opSuccess = true);

    /**
     * @brief Schedule auto relocking with a given timeout
     *
     * @param endpointId    endpoint where DoorLockServer is running
     * @param timeoutSec    timeout in seconds
     */
    void ScheduleAutoRelock(chip::EndpointId endpointId, uint32_t timeoutSec);

    static void DoorLockOnAutoRelockCallback(chip::EndpointId endpointId);

    /**
     * @brief Send generic event
     *
     * @tparam T            Any event type supported by Matter
     * @param endpointId    endpoint where DoorLockServer is running
     * @param event         event object built by caller
     */
    template <typename T>
    void SendEvent(chip::EndpointId endpointId, T & event);

    /**
     * @brief Get generic attribute value
     *
     * @tparam T            attribute value type
     * @param endpointId    endpoint where DoorLockServer is running
     * @param attributeId   attribute Id (used for logging only)
     * @param getFn         attribute getter function as defined in <Accessors.h>
     * @param value         actual attribute value on success
     * @return true         on success (value is set to the actual attribute value)
     * @return false        if attribute reading failed (value is kept unchanged)
     */
    template <typename T>
    bool GetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId,
                      EmberAfStatus (*getFn)(chip::EndpointId endpointId, T * value), T & value) const;

    /**
     * @brief Set generic attribute value
     *
     * @tparam T            attribute value type
     * @param endpointId    endpoint where DoorLockServer is running
     * @param attributeId   attribute Id (used for logging only)
     * @param setFn         attribute setter function as defined in <Accessors.h>
     * @param value         new attribute value
     * @return true         on success
     * @return false        if attribute writing failed
     */
    template <typename T>
    bool SetAttribute(chip::EndpointId endpointId, chip::AttributeId attributeId,
                      EmberAfStatus (*setFn)(chip::EndpointId endpointId, T value), T value);

    friend bool
    emberAfDoorLockClusterLockDoorCallback(chip::app::CommandHandler * commandObj,
                                           const chip::app::ConcreteCommandPath & commandPath,
                                           const chip::app::Clusters::DoorLock::Commands::LockDoor::DecodableType & commandData);

    friend bool emberAfDoorLockClusterUnlockDoorCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::UnlockDoor::DecodableType & commandData);

    friend bool emberAfDoorLockClusterUnlockWithTimeoutCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::UnlockWithTimeout::DecodableType & commandData);

    friend bool emberAfDoorLockClusterSetHolidayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::SetHolidaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterGetHolidayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::GetHolidaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterClearHolidayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::ClearHolidaySchedule::DecodableType & commandData);

    friend bool
    emberAfDoorLockClusterSetUserCallback(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath,
                                          const chip::app::Clusters::DoorLock::Commands::SetUser::DecodableType & commandData);

    friend bool
    emberAfDoorLockClusterGetUserCallback(chip::app::CommandHandler * commandObj,
                                          const chip::app::ConcreteCommandPath & commandPath,
                                          const chip::app::Clusters::DoorLock::Commands::GetUser::DecodableType & commandData);

    friend bool
    emberAfDoorLockClusterClearUserCallback(chip::app::CommandHandler * commandObj,
                                            const chip::app::ConcreteCommandPath & commandPath,
                                            const chip::app::Clusters::DoorLock::Commands::ClearUser::DecodableType & commandData);

    friend bool emberAfDoorLockClusterSetCredentialCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::SetCredential::DecodableType & commandData);

    friend bool emberAfDoorLockClusterGetCredentialStatusCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::GetCredentialStatus::DecodableType & commandData);

    friend bool emberAfDoorLockClusterClearCredentialCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::ClearCredential::DecodableType & commandData);

    friend bool emberAfDoorLockClusterSetWeekDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::SetWeekDaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterGetWeekDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::GetWeekDaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterClearWeekDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::ClearWeekDaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterSetYearDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::SetYearDaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterGetYearDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::GetYearDaySchedule::DecodableType & commandData);

    friend bool emberAfDoorLockClusterClearYearDayScheduleCallback(
        chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath,
        const chip::app::Clusters::DoorLock::Commands::ClearYearDaySchedule::DecodableType & commandData);

    EmberEventControl AutolockEvent; /**< for automatic relock scheduling */

    std::array<EmberAfDoorLockEndpointContext, EMBER_AF_DOOR_LOCK_CLUSTER_SERVER_ENDPOINT_COUNT> mEndpointCtx;

    static DoorLockServer instance;
};

/**
 * @brief Status of the credential slot in the credentials database.
 */
enum class DlCredentialStatus : uint8_t
{
    kAvailable = 0x00, /**< Indicates if credential slot is available. */
    kOccupied  = 0x01, /**< Indicates if credential slot is already occupied. */
};

enum class DlAssetSource : uint8_t
{
    kUnspecified = 0x00,
    kMatterIM    = 0x01,
};

/**
 * @brief Structure that holds the credential information.
 */
struct EmberAfPluginDoorLockCredentialInfo
{
    DlCredentialStatus status;       /**< Indicates if credential slot is occupied or not. */
    DlCredentialType credentialType; /**< Specifies the type of the credential (PIN, RFID, etc.). */
    chip::ByteSpan credentialData;   /**< Credential data bytes. */

    DlAssetSource creationSource;
    chip::FabricIndex createdBy; /**< Index of the fabric that created the user. */

    DlAssetSource modificationSource;
    chip::FabricIndex lastModifiedBy; /**< ID of the fabric that modified the user. */
};

/**
 * @brief Structure that holds user information.
 */
struct EmberAfPluginDoorLockUserInfo
{
    chip::CharSpan userName;                            /**< Name of the user. */
    chip::Span<const DlCredential> credentials;         /**< Credentials that are associated with user (without data).*/
    uint32_t userUniqueId;                              /**< Unique user identifier. */
    DlUserStatus userStatus = DlUserStatus::kAvailable; /**< Status of the user slot (available/occupied). */
    DlUserType userType;                                /**< Type of the user. */
    DlCredentialRule credentialRule;                    /**< Number of supported credentials. */

    DlAssetSource creationSource;
    chip::FabricIndex createdBy; /**< ID of the fabric that created the user. */

    DlAssetSource modificationSource;
    chip::FabricIndex lastModifiedBy; /**< ID of the fabric that modified the user. */
};

/**
 * @brief Status of the schedule slot in the schedule database.
 */
enum class DlScheduleStatus : uint8_t
{
    kAvailable = 0x00, /**< Indicates if schedule slot is available. */
    kOccupied  = 0x01, /**< Indicates if schedule slot is already occupied. */
};

/**
 * @brief Structure that holds week day schedule information.
 */
struct EmberAfPluginDoorLockWeekDaySchedule
{
    DlDaysMaskMap daysMask; /** Indicates the days of the week the Week Day schedule applies for. */
    uint8_t startHour;      /** Starting hour for the Week Day schedule. */
    uint8_t startMinute;    /** Starting minute for the Week Day schedule. */
    uint8_t endHour;        /** Ending hour for the Week Day schedule. */
    uint8_t endMinute;      /** Ending minute for the Week Day schedule. */
};

/**
 * @brief Structure that holds year day schedule information.
 */
struct EmberAfPluginDoorLockYearDaySchedule
{
    uint32_t localStartTime; /** The starting time for the Year Day schedule in Epoch Time in Seconds with local time offset based
                                on the local timezone and DST offset on the day represented by the value. */
    uint32_t localEndTime;   /** The ending time for the Year Day schedule in Epoch Time in Seconds with local time offset based on
                              * the local timezone and DST offset on the day represented by the value. */
};

/**
 * @brief Structure that holds holiday schedule information.
 */
struct EmberAfPluginDoorLockHolidaySchedule
{
    uint32_t localStartTime; /** The starting time for the Holiday schedule in Epoch Time in Seconds with local time offset based
                            on the local timezone and DST offset on the day represented by the value. */
    uint32_t localEndTime;   /** The ending time for the Holiday schedule in Epoch Time in Seconds with local time offset based on
                              * the local timezone and DST offset on the day represented by the value. */
    DlOperatingMode operatingMode; /** Operating mode during the schedule. */
};

/**
 * @brief This callback is called when Door Lock cluster needs to access the Week Day schedule in the schedules database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param weekdayIndex Index of the week day schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     week day schedule (from 1 up to NumberOfWeekDaySchedulesSupportedPerUser).
 * @param userIndex Index of the user to get week day schedule. It is guaranteed to be within limits declared in the spec (from 1 up
 *                  to the value of NumberOfUsersSupported attribute).
 * @param[out] schedule Resulting week day schedule.
 *
 * @retval DlStatus::kSuccess if schedule was retrieved successfully
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
                                          EmberAfPluginDoorLockWeekDaySchedule & schedule);
/**
 * @brief This callback is called when Door Lock cluster needs to access the Year Day schedule in the schedules database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param yearDayIndex Index of the year day schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     year day schedule (from 1 up to NumberOfYearDaySchedulesSupportedPerUser)
 * @param userIndex Index of the user to get year day schedule. It is guaranteed to be within limits declared in the spec (from 1 up
 *                  to the value of NumberOfUsersSupported attribute).
 * @param[out] schedule Resulting year day schedule.
 *
 * @retval DlStatus::kSuccess if schedule was retrieved successfully
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
                                          EmberAfPluginDoorLockYearDaySchedule & schedule);

/**
 * @brief This callback is called when Door Lock cluster needs to access the Holiday schedule in the schedules database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param holidayIndex Index of the holiday schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     holiday schedule (from 1 up to NumberOfHolidaySchedulesSupported)
 * @param[out] schedule Resulting holiday schedule.
 *
 * @retval DlStatus::kSuccess if schedule was retrieved successfully
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockGetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex,
                                          EmberAfPluginDoorLockHolidaySchedule & schedule);

/**
 * @brief This callback is called when Door Lock cluster needs to create, modify or clear the week day schedule in schedules
 * database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param weekdayIndex Index of the week day schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     week day schedule (from 1 up to NumberOfWeekDaySchedulesSupportedPerUser).
 * @param userIndex Index of the user to get year day schedule. It is guaranteed to be within limits declared in the spec (from 1 up
 *                  to the value of NumberOfUsersSupported attribute).
 * @param status New status of the schedule slot (occupied/available). DlScheduleStatus::kAvailable means that the
 *               schedules must be deleted.
 * @param daysMask Indicates the days of the week the Week Day schedule applies for.
 * @param startHour Starting hour for the Week Day schedule.
 * @param startMinute Starting minute for the Week Day schedule
 * @param endHour Ending hour for the Week Day schedule. Guaranteed to be greater or equal to \p startHour.
 * @param endMinute Ending minute for the Week Day schedule. If \p endHour is equal to \p startHour then EndMinute
 *                  is guaranteed to be greater than \p startMinute.
 *
 * @retval DlStatus::kSuccess if schedule was successfully modified
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t weekdayIndex, uint16_t userIndex,
                                          DlScheduleStatus status, DlDaysMaskMap daysMask, uint8_t startHour, uint8_t startMinute,
                                          uint8_t endHour, uint8_t endMinute);
/**
 * @brief This callback is called when Door Lock cluster needs to create, modify or clear the year day schedule in schedules
 * database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param yearDayIndex Index of the year day schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     year day schedule (from 1 up to NumberOfYearDaySchedulesSupportedPerUser).
 * @param userIndex Index of the user to get year day schedule. It is guaranteed to be within limits declared in the spec (from 1 up
 *                  to the value of NumberOfUsersSupported attribute).
 * @param status New status of the schedule slot (occupied/available). DlScheduleStatus::kAvailable means that the
 *               schedules must be deleted.
 * @param localStartTime The starting time for the Year Day schedule in Epoch Time in Seconds with local time offset based on the
 *                       local timezone and DST offset on the day represented by the value.
 * @param localEndTime The ending time for the Year Day schedule in Epoch Time in Seconds with local time offset based on the local
 *                     timezone and DST offset on the day represented by the value. \p localEndTime is guaranteed to be greater than
 *                     \p localStartTime.
 *
 * @retval DlStatus::kSuccess if schedule was successfully modified
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t yearDayIndex, uint16_t userIndex,
                                          DlScheduleStatus status, uint32_t localStartTime, uint32_t localEndTime);

/**
 * @brief This callback is called when Door Lock cluster needs to create, modify or clear the holiday schedule in schedules
 * database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param holidayIndex Index of the holiday schedule to access. It is guaranteed to be within limits declared in the spec for
 *                     holiday schedule (from 1 up to NumberOfHolidaySchedulesSupported).
 * @param status New status of the schedule slot (occupied/available). DlScheduleStatus::kAvailable means that the
 *               schedules must be deleted.
 * @param localStartTime The starting time for the Year Day schedule in Epoch Time in Seconds with local time offset based on the
 *                       local timezone and DST offset on the day represented by the value.
 * @param localEndTime The ending time for the Year Day schedule in Epoch Time in Seconds with local time offset based on the local
 *                     timezone and DST offset on the day represented by the value. \p localEndTime is guaranteed to be greater than
 *                     \p localStartTime.
 * @param operatingMode The operating mode to use during this Holiday schedule start/end time.
 *
 * @retval DlStatus::kSuccess if schedule was successfully modified
 * @retval DlStatus::kNotFound if the schedule or user does not exist
 * @retval DlStatus::kFailure in case of any other failure
 */
DlStatus emberAfPluginDoorLockSetSchedule(chip::EndpointId endpointId, uint8_t holidayIndex, DlScheduleStatus status,
                                          uint32_t localStartTime, uint32_t localEndTime, DlOperatingMode operatingMode);

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

/** @brief 'Language' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newLanguage     language to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnLanguageChange(chip::EndpointId EndpointId,
                                                                                chip::CharSpan newLanguage);

/** @brief 'AutoRelockTime' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newTime         relock time value to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnAutoRelockTimeChange(chip::EndpointId EndpointId,
                                                                                      uint32_t newTime);

/** @brief 'SoundVolume' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newVolume       volume level to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnSoundVolumeChange(chip::EndpointId EndpointId, uint8_t newVolume);

/** @brief 'OperatingMode' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newMode         operating mode to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnOperatingModeChange(chip::EndpointId EndpointId, uint8_t newMode);

/** @brief 'EnableOneTouchLocking' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  enable          true to enable one touch locking, false otherwise
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnEnableOneTouchLockingChange(chip::EndpointId EndpointId,
                                                                                             bool enable);

/** @brief 'EnablePrivacyModeButton' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  enable          true to enable privacy mode button, false otherwise
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnEnablePrivacyModeButtonChange(chip::EndpointId EndpointId,
                                                                                               bool enable);

/** @brief 'WrongCodeEntryLimit' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newLimit        new limit for the number of incorrect PIN attempts to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnWrongCodeEntryLimitChange(chip::EndpointId EndpointId,
                                                                                           uint8_t newLimit);

/** @brief 'UserCodeTemporaryDisableTime' attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  newTime         new number of seconds for which lock will be shut down due to wrong code entry
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status emberAfPluginDoorLockOnUserCodeTemporaryDisableTimeChange(chip::EndpointId EndpointId,
                                                                                                    uint8_t newTime);

/** @note This callback is called for any cluster attribute that has no predefined callback above
 *
 * @brief Cluster attribute pre-change callback
 *
 * @param  EndpointId      endpoint for which attribute is changing
 * @param  attributePath   concrete attribute path that is changing
 * @param  attrType        attribute that is going to be changed
 * @param  attrSize        attribute value storage size
 * @param  attrValue       attribute value to set
 *
 * @retval InteractionModel::Status::Success if attribute change is possible
 * @retval any other InteractionModel::Status value to forbid attribute change
 */
chip::Protocols::InteractionModel::Status
emberAfPluginDoorLockOnUnhandledAttributeChange(chip::EndpointId EndpointId, const chip::app::ConcreteAttributePath & attributePath,
                                                EmberAfAttributeType attrType, uint16_t attrSize, uint8_t * attrValue);

// =============================================================================
// Plugin callbacks that are called by cluster server and should be implemented
// by the server app
// =============================================================================

/**
 * @brief User handler for LockDoor command (server)
 *
 * @param   endpointId      endpoint for which LockDoor command is called
 * @param   pinCode         PIN code (optional)
 * @param   err             error code if door locking failed (set only if retval==false)
 *
 * @retval true on success
 * @retval false if error happenned (err should be set to appropriate error code)
 */
bool emberAfPluginDoorLockOnDoorLockCommand(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pinCode,
                                            DlOperationError & err);

/**
 * @brief User handler for UnlockDoor command (server)
 *
 * @param   endpointId      endpoint for which UnlockDoor command is called
 * @param   pinCode         PIN code (optional)
 * @param   err             error code if door unlocking failed (set only if retval==false)
 *
 * @retval true on success
 * @retval false if error happenned (err should be set to appropriate error code)
 */
bool emberAfPluginDoorLockOnDoorUnlockCommand(chip::EndpointId endpointId, const Optional<chip::ByteSpan> & pinCode,
                                              DlOperationError & err);

/**
 * @brief This callback is called when the AutoRelock timer is expired.
 *
 * @param endpointId ID of the endpoint that contains the door lock to be relocked.
 */
void emberAfPluginDoorLockOnAutoRelock(chip::EndpointId endpointId);

/**
 * @brief This callback is called when Door Lock cluster needs to access the users database.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param userIndex Index of the user to access. It is guaranteed to be within limits declared in the spec (from 1 up to the value
 *                  of NumberOfUsersSupported attribute).
 * @param[out] user Reference to the user information variable which will hold user info upon successful function call.
 *
 * @retval true, if \p userIndex was found in the database and \p user parameter was written with valid data.
 * @retval false, if error occurred.
 */
bool emberAfPluginDoorLockGetUser(chip::EndpointId endpointId, uint16_t userIndex, EmberAfPluginDoorLockUserInfo & user);

/**
 * @brief This callback is called when Door Lock cluster needs to create, modify or clear the user in users database.
 *
 * @note This function is used for creating, modifying and clearing users. It is not guaranteed that the parameters always differ
 *       from current user state. For example, when modifying a single field (say, uniqueId) the user information that is passed
 *       to a function will be the same as the user record except this field.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param userIndex Index of the user to create/modify. It is guaranteed to be within limits declared in the spec (from 1 up to the
 *                  value of NumberOfUsersSupported attribute).
 * @param creator Fabric ID that created the user. Could be kUndefinedFabricIndex (0).
 * @param modifier Fabric ID that was last to modify the user. Could be kUndefinedFabricIndex (0).
 * @param[in] userName Pointer to the user name. Could be an empty string, data is guaranteed not to be a nullptr.
 * @param uniqueId New Unique ID of the user.
 * @param userStatus New status of the user.
 * @param usertype New type of the user.
 * @param credentialRule New credential rule (how many credentials are allowed for user).
 * @param[in] credentials Array of credentials. Size of this array is determined by totalCredentials variable. Could be nullptr
 *            which means that the credentials should be deleted.
 * @param totalCredentials Size of \p credentials array. Could be 0.
 *
 * @retval true, if user pointed by \p userIndex was successfully changed in the database.
 * @retval false, if error occurred while changing the user.
 */
bool emberAfPluginDoorLockSetUser(chip::EndpointId endpointId, uint16_t userIndex, chip::FabricIndex creator,
                                  chip::FabricIndex modifier, const chip::CharSpan & userName, uint32_t uniqueId,
                                  DlUserStatus userStatus, DlUserType usertype, DlCredentialRule credentialRule,
                                  const DlCredential * credentials, size_t totalCredentials);

/**
 * @brief This callback is called when Door Lock cluster needs to access the credential in credentials database.
 *
 * @note The door lock cluster does not assume in any way underlying implementation of the database. Different credential types
 *       may be stored in the single data structure with shared index or separately. Door lock cluster guarantees that the
 *       credentialIndex will always be within the range for a particular credential type.
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param credentialIndex Index of the credential to access. It is guaranteed to be within limits declared in the spec for
 *                        particular credential type. Starts from 1 for all credential types except Programming PIN -- in that case
 *                         it could only be equal to 0.
 * @param credentialType Type of the accessing credential.
 * @param[out] credential Reference to the credential information which will be filled upon successful function call.
 *
 * @retval true, if the credential pointed by \p credentialIndex was found and \p credential parameter was written with valid data.
 * @retval false, if error occurred.
 */
bool emberAfPluginDoorLockGetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, DlCredentialType credentialType,
                                        EmberAfPluginDoorLockCredentialInfo & credential);

/**
 * @brief This callback is called when Door Lock cluster needs to create, modify or clear the credential in credentials database.
 *
 * @note It is guaranteed that the call to this function will not cause any duplicated entries in the database (e.g. entries that
 *       share the same \p credentialType and \p credentialData).
 *
 * @param endpointId ID of the endpoint which contains the lock.
 * @param credentialIndex Index of the credential to access. It is guaranteed to be within limits declared in the spec for
 *                         particular credential type. Starts from 1 for all credential types except Programming PIN -- in that case
 *                         it could only be equal to 0.
 * @param creator Fabric ID that created the user. Could be kUndefinedFabricIndex (0).
 * @param modifier Fabric ID that was last to modify the user. Could be kUndefinedFabricIndex (0).
 * @param credentialStatus New status of the credential slot (occupied/available). DlCredentialStatus::kAvailable means that the
 *                         credential must be deleted.
 * @param credentialType Type of the credential (PIN, RFID, etc.).
 * @param[in] credentialData Data attached to a credential. Can contain nullptr as data which indicates that the data for credential
 *                           should be removed.
 *
 * @retval true, if credential pointed by \p credentialIndex of type \p credentialType was successfully changed in the database.
 * @retval false, if error occurred.
 */
bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t credentialIndex, chip::FabricIndex creator,
                                        chip::FabricIndex modifier, DlCredentialStatus credentialStatus,
                                        DlCredentialType credentialType, const chip::ByteSpan & credentialData);

/**
 * @brief This callback is called when the Door Lock server starts the lockout so the app could be notified about it.
 *
 * @param endpointId ID of the endpoint that contains the door lock to be locked out.
 * @param lockoutEndTime Monotonic time of when lockout ends.
 */
void emberAfPluginDoorLockLockoutStarted(chip::EndpointId endpointId, chip::System::Clock::Timestamp lockoutEndTime);
