/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    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.
 */

#pragma once

#include <access/AccessConfig.h>

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
#include "AccessRestrictionProvider.h"
#endif

#include "AuxiliaryType.h"
#include "Privilege.h"
#include "RequestPath.h"
#include "SubjectDescriptor.h"

#include <lib/core/CHIPCore.h>
#include <lib/core/Global.h>
#include <lib/support/CodeUtils.h>

// Dump function for use during development only (0 for disabled, non-zero for enabled).
#define CHIP_ACCESS_CONTROL_DUMP_ENABLED 0

namespace chip {
namespace Access {

class AccessControl
{
public:
    /**
     * Used by access control to determine if a device type resolves to an endpoint.
     */
    struct DeviceTypeResolver
    {
    public:
        virtual ~DeviceTypeResolver() = default;

        virtual bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint) = 0;
    };

    /**
     * Handle to an entry in the access control list.
     *
     * Must be prepared (`AccessControl::PrepareEntry`) or read (`AccessControl::ReadEntry`) before first use.
     */
    class Entry
    {
    public:
        struct Target
        {
            using Flags                        = unsigned;
            static constexpr Flags kCluster    = 1 << 0;
            static constexpr Flags kEndpoint   = 1 << 1;
            static constexpr Flags kDeviceType = 1 << 2;
            Flags flags                        = 0;
            ClusterId cluster;
            EndpointId endpoint;
            DeviceTypeId deviceType;
        };

        class Delegate
        {
        public:
            Delegate() = default;

            Delegate(const Delegate &)             = delete;
            Delegate & operator=(const Delegate &) = delete;

            virtual ~Delegate() = default;

            virtual void Release() {}

            // Simple getters
            virtual CHIP_ERROR GetAuthMode(AuthMode & authMode) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR GetFabricIndex(FabricIndex & fabricIndex) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR GetPrivilege(Privilege & privilege) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR GetAuxiliaryType(AuxiliaryType & auxiliaryType) const { return CHIP_ERROR_NOT_IMPLEMENTED; }

            // Simple setters
            virtual CHIP_ERROR SetAuthMode(AuthMode authMode) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR SetFabricIndex(FabricIndex fabricIndex) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR SetPrivilege(Privilege privilege) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR SetAuxiliaryType(AuxiliaryType auxiliaryType) { return CHIP_ERROR_NOT_IMPLEMENTED; }

            // Subjects
            virtual CHIP_ERROR GetSubjectCount(size_t & count) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR GetSubject(size_t index, NodeId & subject) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR SetSubject(size_t index, NodeId subject) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR AddSubject(size_t * index, NodeId subject) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR RemoveSubject(size_t index) { return CHIP_ERROR_NOT_IMPLEMENTED; }

            // Targets
            virtual CHIP_ERROR GetTargetCount(size_t & count) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR GetTarget(size_t index, Target & target) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR SetTarget(size_t index, const Target & target) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR AddTarget(size_t * index, const Target & target) { return CHIP_ERROR_NOT_IMPLEMENTED; }
            virtual CHIP_ERROR RemoveTarget(size_t index) { return CHIP_ERROR_NOT_IMPLEMENTED; }
        };

        Entry() = default;

        Entry(Entry && other) : mDelegate(other.mDelegate) { other.mDelegate = &mDefaultDelegate.get(); }

        Entry & operator=(Entry && other)
        {
            if (this != &other)
            {
                mDelegate->Release();
                mDelegate       = other.mDelegate;
                other.mDelegate = &mDefaultDelegate.get();
            }
            return *this;
        }

        Entry(const Entry &)             = delete;
        Entry & operator=(const Entry &) = delete;

        ~Entry() { mDelegate->Release(); }

        // Simple getters
        CHIP_ERROR GetAuthMode(AuthMode & authMode) const { return mDelegate->GetAuthMode(authMode); }
        CHIP_ERROR GetFabricIndex(FabricIndex & fabricIndex) const { return mDelegate->GetFabricIndex(fabricIndex); }
        CHIP_ERROR GetPrivilege(Privilege & privilege) const { return mDelegate->GetPrivilege(privilege); }
        CHIP_ERROR GetAuxiliaryType(AuxiliaryType & auxiliaryType) const { return mDelegate->GetAuxiliaryType(auxiliaryType); }

        // Simple setters
        CHIP_ERROR SetAuthMode(AuthMode authMode) { return mDelegate->SetAuthMode(authMode); }
        CHIP_ERROR SetFabricIndex(FabricIndex fabricIndex) { return mDelegate->SetFabricIndex(fabricIndex); }
        CHIP_ERROR SetPrivilege(Privilege privilege) { return mDelegate->SetPrivilege(privilege); }
        CHIP_ERROR SetAuxiliaryType(AuxiliaryType auxiliaryType) { return mDelegate->SetAuxiliaryType(auxiliaryType); }

        /**
         * Gets the number of subjects.
         *
         * @param [out] count   The number of subjects.
         */
        CHIP_ERROR GetSubjectCount(size_t & count) const { return mDelegate->GetSubjectCount(count); }

        /**
         * Gets the specified subject.
         *
         * @param [in]  index       The index of the subject to get.
         * @param [out] subject     The subject into which to get.
         */
        CHIP_ERROR GetSubject(size_t index, NodeId & subject) const { return mDelegate->GetSubject(index, subject); }

        /**
         * Sets the specified subject.
         *
         * @param [in] index        The index of the subject to set.
         * @param [in] subject      The subject from which to set.
         */
        CHIP_ERROR SetSubject(size_t index, NodeId subject) { return mDelegate->SetSubject(index, subject); }

        /**
         * Adds the specified subject.
         *
         * @param [out] index       The index of the added subject, if not null.
         * @param [in]  subject     The subject to add.
         */
        CHIP_ERROR AddSubject(size_t * index, NodeId subject) { return mDelegate->AddSubject(index, subject); }

        /**
         * Removes the specified subject.
         *
         * @param [in] index        The index of the subject to delete.
         */
        CHIP_ERROR RemoveSubject(size_t index) { return mDelegate->RemoveSubject(index); }

        /**
         * Gets the number of targets.
         *
         * @param [out] count   The number of targets.
         */
        CHIP_ERROR GetTargetCount(size_t & count) const { return mDelegate->GetTargetCount(count); }

        /**
         * Gets the specified target.
         *
         * @param [in]  index       The index of the target to get.
         * @param [out] target      The target into which to get.
         */
        CHIP_ERROR GetTarget(size_t index, Target & target) const { return mDelegate->GetTarget(index, target); }

        /**
         * Sets the specified target.
         *
         * @param [in] index        The index of the target to set.
         * @param [in] target       The target from which to set.
         */
        CHIP_ERROR SetTarget(size_t index, const Target & target) { return mDelegate->SetTarget(index, target); }

        /**
         * Adds the specified target.
         *
         * @param [out] index       The index of the added target, if not null.
         * @param [in]  target      The target to add.
         */
        CHIP_ERROR AddTarget(size_t * index, const Target & target) { return mDelegate->AddTarget(index, target); }

        /**
         * Removes the specified target.
         *
         * @param [in] index        The index of the target to delete.
         */
        CHIP_ERROR RemoveTarget(size_t index) { return mDelegate->RemoveTarget(index); }

        bool HasDefaultDelegate() const { return mDelegate == &mDefaultDelegate.get(); }

        const Delegate & GetDelegate() const { return *mDelegate; }

        Delegate & GetDelegate() { return *mDelegate; }

        void SetDelegate(Delegate & delegate)
        {
            mDelegate->Release();
            mDelegate = &delegate;
        }

        void ResetDelegate()
        {
            mDelegate->Release();
            mDelegate = &mDefaultDelegate.get();
        }

        /**
         * Validate whether an ACL Entry is valid and complies with all defined constraints.
         *
         * @retval true if all the fields within the Entry are valid and compliant.
         */
        bool IsValid() const;

    private:
        static Global<Delegate> mDefaultDelegate;
        Delegate * mDelegate = &mDefaultDelegate.get();
    };

    /**
     * Handle to an entry iterator in the access control list.
     *
     * Must be initialized (`AccessControl::Entries`) before first use.
     */
    class EntryIterator
    {
    public:
        class Delegate
        {
        public:
            Delegate() = default;

            Delegate(const Delegate &)             = delete;
            Delegate & operator=(const Delegate &) = delete;

            virtual ~Delegate() = default;

            virtual void Release() {}

            virtual CHIP_ERROR Next(Entry & entry) { return CHIP_ERROR_SENTINEL; }
        };

        EntryIterator() = default;

        EntryIterator(const EntryIterator &)             = delete;
        EntryIterator & operator=(const EntryIterator &) = delete;

        ~EntryIterator() { mDelegate->Release(); }

        CHIP_ERROR Next(Entry & entry) { return mDelegate->Next(entry); }

        const Delegate & GetDelegate() const { return *mDelegate; }

        Delegate & GetDelegate() { return *mDelegate; }

        void SetDelegate(Delegate & delegate)
        {
            mDelegate->Release();
            mDelegate = &delegate;
        }

        void ResetDelegate()
        {
            mDelegate->Release();
            mDelegate = &mDefaultDelegate.get();
        }

    private:
        static Global<Delegate> mDefaultDelegate;
        Delegate * mDelegate = &mDefaultDelegate.get();
    };

    /**
     * Used by access control to notify of changes in access control list.
     */
    class EntryListener
    {
    public:
        enum class ChangeType
        {
            kAdded   = 1,
            kRemoved = 2,
            kUpdated = 3
        };

        virtual ~EntryListener() = default;

        /**
         * Notifies of a change in the access control list.
         *
         * The fabric is indicated by its own parameter. If available, a subject descriptor will
         * have more detail (and its fabric index will match). A best effort is made to provide
         * the latest value of the changed entry.
         *
         * @param [in] subjectDescriptor Optional (if available) subject descriptor for this operation.
         * @param [in] fabric            Index of fabric in which entry has changed.
         * @param [in] index             Index of entry to which has changed (relative to fabric).
         * @param [in] entry             Optional (best effort) latest value of entry which has changed.
         * @param [in] changeType        Type of change.
         */
        virtual void OnEntryChanged(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index,
                                    const Entry * entry, ChangeType changeType) = 0;

    private:
        EntryListener * mNext = nullptr;

        friend class AccessControl;
    };

    class Delegate
    {
    public:
        Delegate() = default;

        Delegate(const Delegate &)             = delete;
        Delegate & operator=(const Delegate &) = delete;

        virtual ~Delegate() = default;

        virtual void Release() {}

        virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; }
        virtual void Finish() {}

        // Capabilities
        virtual CHIP_ERROR GetMaxEntriesPerFabric(size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        virtual CHIP_ERROR GetMaxSubjectsPerEntry(size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        virtual CHIP_ERROR GetMaxTargetsPerEntry(size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        virtual CHIP_ERROR GetMaxEntryCount(size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        // Actualities
        virtual CHIP_ERROR GetEntryCount(FabricIndex fabric, size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        virtual CHIP_ERROR GetEntryCount(size_t & value) const
        {
            value = 0;
            return CHIP_NO_ERROR;
        }

        // Preparation
        virtual CHIP_ERROR PrepareEntry(Entry & entry) { return CHIP_NO_ERROR; }

        // CRUD
        virtual CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }
        virtual CHIP_ERROR ReadEntry(size_t index, Entry & entry, const FabricIndex * fabricIndex) const { return CHIP_NO_ERROR; }
        virtual CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }
        virtual CHIP_ERROR DeleteEntry(size_t index, const FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }

        // Iteration
        virtual CHIP_ERROR Entries(EntryIterator & iterator, const FabricIndex * fabricIndex) const { return CHIP_NO_ERROR; }

        virtual CHIP_ERROR AuxiliaryEntries(EntryIterator & iterator, const FabricIndex * fabricIndex) const
        {
            return CHIP_ERROR_NOT_IMPLEMENTED;
        }

        // Check
        // Return CHIP_NO_ERROR if allowed, CHIP_ERROR_ACCESS_DENIED if denied,
        // CHIP_ERROR_NOT_IMPLEMENTED to use the default check algorithm (against entries),
        // or any other CHIP_ERROR if another error occurred.
        virtual CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
                                 Privilege requestPrivilege)
        {
            return CHIP_ERROR_ACCESS_DENIED;
        }
    };

    AccessControl() = default;

    AccessControl(const AccessControl &)             = delete;
    AccessControl & operator=(const AccessControl &) = delete;

    ~AccessControl()
    {
        if (IsGroupAuxiliaryDelegateRegistered())
        {
            mGroupAuxDelegate->Release();
        }

        // Never-initialized AccessControl instances will not have the delegate set.
        if (IsInitialized())
        {
            mDelegate->Release();
        }
    }

    /**
     * Initialize the access control module. Must be called before first use.
     *
     * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if called more than once,
     *         CHIP_ERROR_INVALID_ARGUMENT if delegate is null, or other fatal error.
     */
    CHIP_ERROR Init(AccessControl::Delegate * delegate, DeviceTypeResolver & deviceTypeResolver);

    /**
     * Deinitialize the access control module. Must be called when finished.
     */
    void Finish();

    // Capabilities
    CHIP_ERROR GetMaxEntriesPerFabric(size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetMaxEntriesPerFabric(value);
    }

    CHIP_ERROR GetMaxSubjectsPerEntry(size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetMaxSubjectsPerEntry(value);
    }

    CHIP_ERROR GetMaxTargetsPerEntry(size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetMaxTargetsPerEntry(value);
    }

    CHIP_ERROR GetMaxEntryCount(size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetMaxEntryCount(value);
    }

    // Actualities
    CHIP_ERROR GetEntryCount(FabricIndex fabric, size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetEntryCount(fabric, value);
    }

    CHIP_ERROR GetEntryCount(size_t & value) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->GetEntryCount(value);
    }

    /**
     * Prepares an entry.
     *
     * An entry must be prepared or read (`ReadEntry`) before first use.
     *
     * @param [in] entry        Entry to prepare.
     */
    CHIP_ERROR PrepareEntry(Entry & entry)
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->PrepareEntry(entry);
    }

    /**
     * Creates an entry in the access control list.
     *
     * @param [in]  subjectDescriptor Optional subject descriptor for this operation.
     * @param [in]  fabric            Index of fabric in which to create entry.
     * @param [out] index             (If not nullptr) index of created entry (relative to fabric).
     * @param [in]  entry             Entry from which created entry is copied.
     */
    CHIP_ERROR CreateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t * index, const Entry & entry);

    /**
     * Creates an entry in the access control list.
     *
     * @param [out] index       Entry index of created entry, if not null. May be relative to `fabricIndex`.
     * @param [in]  entry       Entry from which to copy.
     * @param [out] fabricIndex Fabric index of created entry, if not null, in which case entry `index` will be relative to fabric.
     */
    CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex = nullptr)
    {
        VerifyOrReturnError(entry.IsValid(), CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->CreateEntry(index, entry, fabricIndex);
    }

    /**
     * Reads an entry in the access control list.
     *
     * @param [in] fabric            Index of fabric in which to read entry.
     * @param [in] index             Index of entry to read (relative to fabric).
     * @param [in] entry             Entry into which read entry is copied.
     */
    CHIP_ERROR ReadEntry(FabricIndex fabric, size_t index, Entry & entry) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->ReadEntry(index, entry, &fabric);
    }

    /**
     * Reads an entry from the access control list.
     *
     * @param [in]  index       Entry index of entry to read. May be relative to `fabricIndex`.
     * @param [out] entry       Entry into which to copy.
     * @param [in]  fabricIndex Fabric to which entry `index` is relative, if not null.
     */
    CHIP_ERROR ReadEntry(size_t index, Entry & entry, const FabricIndex * fabricIndex = nullptr) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->ReadEntry(index, entry, fabricIndex);
    }

    /**
     * Updates an entry in the access control list.
     *
     * @param [in] subjectDescriptor Optional subject descriptor for this operation.
     * @param [in] fabric            Index of fabric in which to update entry.
     * @param [in] index             Index of entry to update (relative to fabric).
     * @param [in] entry             Entry from which updated entry is copied.
     */
    CHIP_ERROR UpdateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index, const Entry & entry);

    /**
     * Updates an entry in the access control list.
     *
     * @param [in] index        Entry index of entry to update, if not null. May be relative to `fabricIndex`.
     * @param [in] entry        Entry from which to copy.
     * @param [in] fabricIndex  Fabric to which entry `index` is relative, if not null.
     */
    CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex = nullptr)
    {
        VerifyOrReturnError(entry.IsValid(), CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->UpdateEntry(index, entry, fabricIndex);
    }

    /**
     * Deletes an entry in the access control list.
     *
     * @param [in] subjectDescriptor Optional subject descriptor for this operation.
     * @param [in] fabric            Index of fabric in which to delete entry.
     * @param [in] index             Index of entry to delete (relative to fabric).
     */
    CHIP_ERROR DeleteEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index);

    /**
     * Deletes an entry from the access control list.
     *
     * @param [in] index        Entry index of entry to delete. May be relative to `fabricIndex`.
     * @param [in] fabricIndex  Fabric to which entry `index` is relative, if not null.
     */
    CHIP_ERROR DeleteEntry(size_t index, const FabricIndex * fabricIndex = nullptr)
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->DeleteEntry(index, fabricIndex);
    }

    /**
     * @brief Remove all ACL entries for the given fabricIndex
     *
     * @param[in] fabricIndex fabric index for which to remove all entries
     */
    CHIP_ERROR DeleteAllEntriesForFabric(FabricIndex fabricIndex)
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

        CHIP_ERROR stickyError = CHIP_NO_ERROR;

        // Remove access control entries in reverse order (it could be any order, but reverse order
        // will cause less churn in persistent storage).
        size_t aclCount = 0;
        if (GetEntryCount(fabricIndex, aclCount) == CHIP_NO_ERROR)
        {
            while (aclCount)
            {
                CHIP_ERROR err = DeleteEntry(nullptr, fabricIndex, --aclCount);
                stickyError    = (stickyError == CHIP_NO_ERROR) ? err : stickyError;
            }
        }

        return stickyError;
    }

    /**
     * Iterates over entries in the access control list.
     *
     * @param [in]  fabricIndex   Fabric over which to iterate entries.
     * @param [out] iterator Iterator controlling the iteration.
     */
    CHIP_ERROR Entries(FabricIndex fabricIndex, EntryIterator & iterator) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->Entries(iterator, &fabricIndex);
    }

    /**
     * Iterates over entries in the access control list.
     *
     * @param [out] iterator    Iterator controlling the iteration.
     * @param [in]  fabricIndex Iteration is confined to fabric, if not null.
     */
    CHIP_ERROR Entries(EntryIterator & iterator, const FabricIndex * fabricIndex = nullptr) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        return mDelegate->Entries(iterator, fabricIndex);
    }

    /**
     * Iterates over auxiliary entries for the given fabric.
     *
     * @param [in]  fabricIndex   Fabric index for which to iterate auxiliary entries.
     * @param [out] iterator      Iterator controlling the iteration.
     */
    CHIP_ERROR AuxiliaryEntries(FabricIndex fabricIndex, EntryIterator & iterator) const
    {
        VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
        VerifyOrReturnError(IsGroupAuxiliaryDelegateRegistered(), CHIP_ERROR_NOT_IMPLEMENTED);
        return mGroupAuxDelegate->AuxiliaryEntries(iterator, &fabricIndex);
    }

    // Adds a listener to the end of the listener list, if not already in the list.
    void AddEntryListener(EntryListener & listener);

    // Removes a listener from the listener list, if in the list.
    void RemoveEntryListener(EntryListener & listener);

    /**
     * @brief Registers a delegate to handle auxiliary access control entries. There
     * can only be 1 group auxiliary access control delegate registered at a time. To
     * replace the delegate after one has been set previously, one MUST unregister the
     * currently set delegate before calling this registration function.
     *
     * @param[in] delegate The delegate to register.
     *
     * @retval #CHIP_ERROR_INVALID_ARGUMENT if the delegate is null.
     * @retval #CHIP_ERROR_INCORRECT_STATE if a delegate is already registered.
     * @retval #CHIP_NO_ERROR on success.
     */
    CHIP_ERROR RegisterGroupAuxiliaryDelegate(Delegate * delegate)
    {
        VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(mGroupAuxDelegate == nullptr, CHIP_ERROR_INCORRECT_STATE);
        mGroupAuxDelegate = delegate;
        return CHIP_NO_ERROR;
    }

    bool IsGroupAuxiliaryDelegateRegistered() const { return (mGroupAuxDelegate != nullptr); }

    /**
     * @brief Unregisters the delegate handling auxiliary access control entries.
     */
    void UnregisterGroupAuxiliaryDelegate()
    {
        if (IsGroupAuxiliaryDelegateRegistered())
        {
            mGroupAuxDelegate->Release();
            mGroupAuxDelegate = nullptr;
        }
    }

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
    // Set an optional AcceessRestriction object for MNGD feature.
    void SetAccessRestrictionProvider(AccessRestrictionProvider * accessRestrictionProvider)
    {
        mAccessRestrictionProvider = accessRestrictionProvider;
    }

    AccessRestrictionProvider * GetAccessRestrictionProvider() { return mAccessRestrictionProvider; }
#endif

    /**
     * Check whether or not Access Restriction List is supported.
     *
     * @retval true if Access Restriction List is supported.
     */
    bool IsAccessRestrictionListSupported() const;

    /**
     * Check whether access (by a subject descriptor, to a request path,
     * requiring a privilege) should be allowed or denied.
     *
     * If an AccessRestrictionProvider object is set, it will be checked for additional access restrictions.
     *
     * @retval #CHIP_ERROR_ACCESS_DENIED if denied.
     * @retval other errors should also be treated as denied.
     * @retval #CHIP_NO_ERROR if allowed.
     */
    CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege requestPrivilege);

#if CHIP_ACCESS_CONTROL_DUMP_ENABLED
    CHIP_ERROR Dump(const Entry & entry);
#endif

private:
    bool IsInitialized() const { return (mDelegate != nullptr); }

    void NotifyEntryChanged(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index, const Entry * entry,
                            EntryListener::ChangeType changeType);

    /**
     * Check ACL for whether access (by a subject descriptor, to a request path,
     * requiring a privilege) should be allowed or denied.
     */
    CHIP_ERROR CheckACL(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege requestPrivilege);

    /**
     * Check CommissioningARL or ARL (as appropriate) for whether access (by a
     * subject descriptor, to a request path, requiring a privilege) should
     * be allowed or denied.
     */
    CHIP_ERROR CheckARL(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege requestPrivilege);

private:
    Delegate * mDelegate = nullptr;

    // This is an access control delegate that is specifically set to handle auxiliary ACL entries
    // based on group information. It is part of server init params, and can also be set at runtime using
    // RegisterGroupAuxiliaryDelegate(). It is needed for functionality in the groupcast cluster protected by
    // the LN feature, and the access control cluster protected by the AUX feature. It is expected that
    // this delegate will have an implementation of the AuxiliaryEntries() funciton for reporting these
    // entries. It is also expected to implement a Check() function to actually use these entries
    // to approve/deny access control.
    Delegate * mGroupAuxDelegate = nullptr;

    DeviceTypeResolver * mDeviceTypeResolver = nullptr;

    EntryListener * mEntryListener = nullptr;

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
    AccessRestrictionProvider * mAccessRestrictionProvider;
#endif
};

/**
 * Get the global instance set by SetAccessControl, or the default.
 *
 * Calls to this function must be synchronized externally.
 */
AccessControl & GetAccessControl();

/**
 * Set the global instance returned by GetAccessControl.
 *
 * Calls to this function must be synchronized externally.
 */
void SetAccessControl(AccessControl & accessControl);

/**
 * Reset the global instance to the default.
 *
 * Calls to this function must be synchronized externally.
 */
void ResetAccessControlToDefault();

} // namespace Access
} // namespace chip
