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

// Included for the default AccessControlDelegate logging enables/disables.
// See `chip_access_control_policy_logging_verbosity` in `src/app/BUILD.gn` for
// the levels available.
#include <app/AppConfig.h>

#include "AccessControl.h"

#include <lib/core/Global.h>
#include <lib/support/TypeTraits.h>

#include <credentials/GroupDataProvider.h>

namespace chip {
namespace Access {

using chip::CATValues;
using chip::FabricIndex;
using chip::NodeId;

namespace {

Global<AccessControl> defaultAccessControl;
AccessControl * globalAccessControl = nullptr; // lazily defaulted to defaultAccessControl in GetAccessControl

static_assert(((unsigned(Privilege::kAdminister) & unsigned(Privilege::kManage)) == 0) &&
                  ((unsigned(Privilege::kAdminister) & unsigned(Privilege::kOperate)) == 0) &&
                  ((unsigned(Privilege::kAdminister) & unsigned(Privilege::kView)) == 0) &&
                  ((unsigned(Privilege::kAdminister) & unsigned(Privilege::kProxyView)) == 0) &&
                  ((unsigned(Privilege::kManage) & unsigned(Privilege::kOperate)) == 0) &&
                  ((unsigned(Privilege::kManage) & unsigned(Privilege::kView)) == 0) &&
                  ((unsigned(Privilege::kManage) & unsigned(Privilege::kProxyView)) == 0) &&
                  ((unsigned(Privilege::kOperate) & unsigned(Privilege::kView)) == 0) &&
                  ((unsigned(Privilege::kOperate) & unsigned(Privilege::kProxyView)) == 0) &&
                  ((unsigned(Privilege::kView) & unsigned(Privilege::kProxyView)) == 0),
              "Privilege bits must be unique");

bool CheckRequestPrivilegeAgainstEntryPrivilege(Privilege requestPrivilege, Privilege entryPrivilege)
{
    switch (entryPrivilege)
    {
    case Privilege::kView:
        return requestPrivilege == Privilege::kView;
    case Privilege::kProxyView:
        return requestPrivilege == Privilege::kProxyView || requestPrivilege == Privilege::kView;
    case Privilege::kOperate:
        return requestPrivilege == Privilege::kOperate || requestPrivilege == Privilege::kView;
    case Privilege::kManage:
        return requestPrivilege == Privilege::kManage || requestPrivilege == Privilege::kOperate ||
            requestPrivilege == Privilege::kView;
    case Privilege::kAdminister:
        return requestPrivilege == Privilege::kAdminister || requestPrivilege == Privilege::kManage ||
            requestPrivilege == Privilege::kOperate || requestPrivilege == Privilege::kView ||
            requestPrivilege == Privilege::kProxyView;
    }
    return false;
}

constexpr bool IsValidCaseNodeId(NodeId aNodeId)
{
    if (IsOperationalNodeId(aNodeId))
    {
        return true;
    }

    if (IsCASEAuthTag(aNodeId) && (GetCASEAuthTagVersion(CASEAuthTagFromNodeId(aNodeId)) != 0))
    {
        return true;
    }

    return false;
}

constexpr bool IsValidGroupNodeId(NodeId aNodeId)
{
    return IsGroupId(aNodeId) && IsValidGroupId(GroupIdFromNodeId(aNodeId));
}

#if CHIP_PROGRESS_LOGGING && CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1

char GetAuthModeStringForLogging(AuthMode authMode)
{
    switch (authMode)
    {
    case AuthMode::kNone:
        return 'n';
    case AuthMode::kInternalDeviceAccess:
        return 'i';
    case AuthMode::kPase:
        return 'p';
    case AuthMode::kCase:
        return 'c';
    case AuthMode::kGroup:
        return 'g';
    }
    return 'u';
}

constexpr int kCharsPerCatForLogging = 11; // including final null terminator

char * GetCatStringForLogging(char * buf, size_t size, const CATValues & cats)
{
    if (size == 0)
    {
        return nullptr;
    }
    char * p         = buf;
    char * const end = buf + size;
    *p               = '\0';
    // Format string chars needed:
    //   1 for comma (optional)
    //   2 for 0x prefix
    //   8 for 32-bit hex value
    //   1 for null terminator (at end)
    static constexpr char fmtWithoutComma[] = "0x%08" PRIX32;
    static constexpr char fmtWithComma[]    = ",0x%08" PRIX32;
    constexpr int countWithoutComma         = 10;
    constexpr int countWithComma            = countWithoutComma + 1;
    bool withComma                          = false;
    for (auto cat : cats.values)
    {
        if (cat == chip::kUndefinedCAT)
        {
            break;
        }
        snprintf(p, static_cast<size_t>(end - p), withComma ? fmtWithComma : fmtWithoutComma, cat);
        p += withComma ? countWithComma : countWithoutComma;
        if (p >= end)
        {
            // Output was truncated.
            p = end - ((size < 4) ? size : 4);
            while (*p)
            {
                // Indicate truncation if possible.
                *p++ = '.';
            }
            break;
        }
        withComma = true;
    }
    return buf;
}

char GetPrivilegeStringForLogging(Privilege privilege)
{
    switch (privilege)
    {
    case Privilege::kView:
        return 'v';
    case Privilege::kProxyView:
        return 'p';
    case Privilege::kOperate:
        return 'o';
    case Privilege::kManage:
        return 'm';
    case Privilege::kAdminister:
        return 'a';
    }
    return 'u';
}

char GetAuxiliaryTypeStringForLogging(AuxiliaryType auxiliaryType)
{
    switch (auxiliaryType)
    {
    case AuxiliaryType::kSystem:
        return 's';
    case AuxiliaryType::kGroupcast:
        return 'g';
    default:
        return 'u';
    }
}

char GetRequestTypeStringForLogging(RequestType requestType)
{
    switch (requestType)
    {
    case RequestType::kAttributeReadRequest:
        return 'r';
    case RequestType::kAttributeWriteRequest:
        return 'w';
    case RequestType::kCommandInvokeRequest:
        return 'i';
    case RequestType::kEventReadRequest:
        return 'e';
    default:
        return '?';
    }
}

#endif // CHIP_PROGRESS_LOGGING && CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1

} // namespace

Global<AccessControl::Entry::Delegate> AccessControl::Entry::mDefaultDelegate;
Global<AccessControl::EntryIterator::Delegate> AccessControl::EntryIterator::mDefaultDelegate;

CHIP_ERROR AccessControl::Init(AccessControl::Delegate * delegate, DeviceTypeResolver & deviceTypeResolver)
{
    VerifyOrReturnError(!IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

    ChipLogProgress(DataManagement, "AccessControl: initializing");

    VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    CHIP_ERROR retval = delegate->Init();
    if (retval == CHIP_NO_ERROR)
    {
        mDelegate           = delegate;
        mDeviceTypeResolver = &deviceTypeResolver;
    }

    return retval;
}

void AccessControl::Finish()
{
    VerifyOrReturn(IsInitialized());
    ChipLogProgress(DataManagement, "AccessControl: finishing");
    mDelegate->Finish();
    mDelegate = nullptr;

    if (IsGroupAuxiliaryDelegateRegistered())
    {
        mGroupAuxDelegate->Finish();
        UnregisterGroupAuxiliaryDelegate();
    }
}

CHIP_ERROR AccessControl::CreateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t * index,
                                      const Entry & entry)
{
    VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);

    size_t count    = 0;
    size_t maxCount = 0;
    ReturnErrorOnFailure(mDelegate->GetEntryCount(fabric, count));
    ReturnErrorOnFailure(mDelegate->GetMaxEntriesPerFabric(maxCount));

    VerifyOrReturnError((count + 1) <= maxCount, CHIP_ERROR_BUFFER_TOO_SMALL);

    VerifyOrReturnError(entry.IsValid(), CHIP_ERROR_INVALID_ARGUMENT);

    size_t i = 0;
    ReturnErrorOnFailure(mDelegate->CreateEntry(&i, entry, &fabric));

    if (index)
    {
        *index = i;
    }

    NotifyEntryChanged(subjectDescriptor, fabric, i, &entry, EntryListener::ChangeType::kAdded);
    return CHIP_NO_ERROR;
}

CHIP_ERROR AccessControl::UpdateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index,
                                      const Entry & entry)
{
    VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnError(entry.IsValid(), CHIP_ERROR_INVALID_ARGUMENT);
    ReturnErrorOnFailure(mDelegate->UpdateEntry(index, entry, &fabric));
    NotifyEntryChanged(subjectDescriptor, fabric, index, &entry, EntryListener::ChangeType::kUpdated);
    return CHIP_NO_ERROR;
}

CHIP_ERROR AccessControl::DeleteEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index)
{
    VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
    Entry entry;
    Entry * p = nullptr;
    if (mEntryListener != nullptr && ReadEntry(fabric, index, entry) == CHIP_NO_ERROR)
    {
        p = &entry;
    }
    ReturnErrorOnFailure(mDelegate->DeleteEntry(index, &fabric));
    if (p && p->HasDefaultDelegate())
    {
        // The entry was read prior to deletion so its latest value could be provided
        // to the listener after deletion. If it's been reset to its default delegate,
        // that best effort attempt to retain the latest value failed. This is
        // regrettable but OK.
        p = nullptr;
    }
    NotifyEntryChanged(subjectDescriptor, fabric, index, p, EntryListener::ChangeType::kRemoved);
    return CHIP_NO_ERROR;
}

void AccessControl::AddEntryListener(EntryListener & listener)
{
    if (mEntryListener == nullptr)
    {
        mEntryListener = &listener;
        listener.mNext = nullptr;
        return;
    }

    for (EntryListener * l = mEntryListener; /**/; l = l->mNext)
    {
        if (l == &listener)
        {
            return;
        }

        if (l->mNext == nullptr)
        {
            l->mNext       = &listener;
            listener.mNext = nullptr;
            return;
        }
    }
}

void AccessControl::RemoveEntryListener(EntryListener & listener)
{
    if (mEntryListener == &listener)
    {
        mEntryListener = listener.mNext;
        listener.mNext = nullptr;
        return;
    }

    for (EntryListener * l = mEntryListener; l != nullptr; l = l->mNext)
    {
        if (l->mNext == &listener)
        {
            l->mNext       = listener.mNext;
            listener.mNext = nullptr;
            return;
        }
    }
}

bool AccessControl::IsAccessRestrictionListSupported() const
{
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
    return mAccessRestrictionProvider != nullptr;
#else
    return false;
#endif
}

CHIP_ERROR AccessControl::Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
                                Privilege requestPrivilege)
{
    VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
    VerifyOrReturnError(IsValidPrivilege(requestPrivilege), CHIP_ERROR_INVALID_ARGUMENT);

    CHIP_ERROR result = CheckACL(subjectDescriptor, requestPath, requestPrivilege);

    if ((CHIP_NO_ERROR != result) && (Access::AuthMode::kGroup == subjectDescriptor.authMode) &&
        (Access::RequestType::kCommandInvokeRequest == requestPath.requestType) &&
        (Access::Privilege::kOperate == requestPrivilege) && IsGroupId(subjectDescriptor.subject))
    {
        Credentials::GroupDataProvider * groups = Credentials::GetGroupDataProvider();
        VerifyOrReturnError(nullptr != groups, result);
        Credentials::GroupDataProvider::GroupInfo info;
        GroupId gid = GroupIdFromNodeId(subjectDescriptor.subject);
        ReturnErrorOnFailure(groups->GetGroupInfo(subjectDescriptor.fabricIndex, gid, info));
        if (info.HasAuxiliaryACL() && IsGroupAuxiliaryDelegateRegistered())
        {
            result = mGroupAuxDelegate->Check(subjectDescriptor, requestPath, requestPrivilege);
        }
    }

    // CheckARL runs last: it must apply to grants from ACL or the AuxiliaryACL fallback above.
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
    if (result == CHIP_NO_ERROR)
    {
        result = CheckARL(subjectDescriptor, requestPath, requestPrivilege);
    }
#endif

    return result;
}

CHIP_ERROR AccessControl::CheckACL(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
                                   Privilege requestPrivilege)
{
#if CHIP_PROGRESS_LOGGING && CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
    {
        constexpr size_t kMaxCatsToLog = 6;
        char catLogBuf[kMaxCatsToLog * kCharsPerCatForLogging];
        ChipLogProgress(DataManagement,
                        "AccessControl: checking f=%u a=%c s=0x" ChipLogFormatX64 " t=%s c=" ChipLogFormatMEI " e=%u p=%c r=%c",
                        subjectDescriptor.fabricIndex, GetAuthModeStringForLogging(subjectDescriptor.authMode),
                        ChipLogValueX64(subjectDescriptor.subject),
                        GetCatStringForLogging(catLogBuf, sizeof(catLogBuf), subjectDescriptor.cats),
                        ChipLogValueMEI(requestPath.cluster), requestPath.endpoint, GetPrivilegeStringForLogging(requestPrivilege),
                        GetRequestTypeStringForLogging(requestPath.requestType));
    }
#endif // CHIP_PROGRESS_LOGGING && CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1

    {
        CHIP_ERROR result = mDelegate->Check(subjectDescriptor, requestPath, requestPrivilege);
        if (result != CHIP_ERROR_NOT_IMPLEMENTED)
        {
#if CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 0
            ChipLogProgress(DataManagement, "AccessControl: %s (delegate)",
                            (result == CHIP_NO_ERROR)                  ? "allowed"
                                : (result == CHIP_ERROR_ACCESS_DENIED) ? "denied"
                                                                       : "error");
#else
            if (result != CHIP_NO_ERROR)
            {
                ChipLogProgress(DataManagement, "AccessControl: %s (delegate)",
                                (result == CHIP_ERROR_ACCESS_DENIED) ? "denied" : "error");
            }
#endif // CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 0

            return result;
        }
    }

    // Operational PASE not supported for v1.0, so PASE implies commissioning, which has highest privilege.
    // Currently, subject descriptor is only PASE if this node is the responder (aka commissionee);
    // if this node is the initiator (aka commissioner) then the subject descriptor remains blank.
    if (subjectDescriptor.authMode == AuthMode::kPase)
    {
#if CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
        ChipLogProgress(DataManagement, "AccessControl: implicit admin (PASE)");
#endif // CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
        return CHIP_NO_ERROR;
    }

    EntryIterator iterator;
    ReturnErrorOnFailure(Entries(iterator, &subjectDescriptor.fabricIndex));

    Entry entry;
    while (iterator.Next(entry) == CHIP_NO_ERROR)
    {
        AuthMode authMode = AuthMode::kNone;
        ReturnErrorOnFailure(entry.GetAuthMode(authMode));
        // Operational PASE not supported for v1.0.
        VerifyOrReturnError(authMode == AuthMode::kCase || authMode == AuthMode::kGroup, CHIP_ERROR_INCORRECT_STATE);
        if (authMode != subjectDescriptor.authMode)
        {
            continue;
        }

        Privilege privilege = Privilege::kView;
        ReturnErrorOnFailure(entry.GetPrivilege(privilege));
        if (!CheckRequestPrivilegeAgainstEntryPrivilege(requestPrivilege, privilege))
        {
            continue;
        }

        size_t subjectCount = 0;
        ReturnErrorOnFailure(entry.GetSubjectCount(subjectCount));
        if (subjectCount > 0)
        {
            bool subjectMatched = false;
            for (size_t i = 0; i < subjectCount; ++i)
            {
                NodeId subject = kUndefinedNodeId;
                ReturnErrorOnFailure(entry.GetSubject(i, subject));
                if (IsOperationalNodeId(subject))
                {
                    VerifyOrReturnError(authMode == AuthMode::kCase, CHIP_ERROR_INCORRECT_STATE);
                    if (subject == subjectDescriptor.subject)
                    {
                        subjectMatched = true;
                        break;
                    }
                }
                else if (IsCASEAuthTag(subject))
                {
                    VerifyOrReturnError(authMode == AuthMode::kCase, CHIP_ERROR_INCORRECT_STATE);
                    if (subjectDescriptor.cats.CheckSubjectAgainstCATs(subject))
                    {
                        subjectMatched = true;
                        break;
                    }
                }
                else if (IsGroupId(subject))
                {
                    VerifyOrReturnError(authMode == AuthMode::kGroup, CHIP_ERROR_INCORRECT_STATE);
                    if (subject == subjectDescriptor.subject)
                    {
                        subjectMatched = true;
                        break;
                    }
                }
                else
                {
                    // Operational PASE not supported for v1.0.
                    return CHIP_ERROR_INCORRECT_STATE;
                }
            }
            if (!subjectMatched)
            {
                continue;
            }
        }

        size_t targetCount = 0;
        ReturnErrorOnFailure(entry.GetTargetCount(targetCount));
        if (targetCount > 0)
        {
            bool targetMatched = false;
            for (size_t i = 0; i < targetCount; ++i)
            {
                Entry::Target target;
                ReturnErrorOnFailure(entry.GetTarget(i, target));
                if ((target.flags & Entry::Target::kCluster) && target.cluster != requestPath.cluster)
                {
                    continue;
                }
                if ((target.flags & Entry::Target::kEndpoint) && target.endpoint != requestPath.endpoint)
                {
                    continue;
                }
                if (target.flags & Entry::Target::kDeviceType &&
                    !mDeviceTypeResolver->IsDeviceTypeOnEndpoint(target.deviceType, requestPath.endpoint))
                {
                    continue;
                }
                targetMatched = true;
                break;
            }
            if (!targetMatched)
            {
                continue;
            }
        }
        // Entry passed all checks: access is allowed.

#if CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 0
        ChipLogProgress(DataManagement, "AccessControl: allowed");
#endif // CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 0

        return CHIP_NO_ERROR;
    }

    // No entry was found which passed all checks: access is denied.
    ChipLogProgress(DataManagement, "AccessControl: denied");
    return CHIP_ERROR_ACCESS_DENIED;
}

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
CHIP_ERROR AccessControl::CheckARL(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
                                   Privilege requestPrivilege)
{
    CHIP_ERROR result = CHIP_NO_ERROR;

    VerifyOrReturnError(requestPath.requestType != RequestType::kRequestTypeUnknown, CHIP_ERROR_INVALID_ARGUMENT);

    if (!IsAccessRestrictionListSupported())
    {
        // Access Restriction support is compiled in, but not configured/enabled. Nothing to restrict.
        return CHIP_NO_ERROR;
    }

    if (subjectDescriptor.isCommissioning)
    {
        result = mAccessRestrictionProvider->CheckForCommissioning(subjectDescriptor, requestPath);
    }
    else
    {
        result = mAccessRestrictionProvider->Check(subjectDescriptor, requestPath);
    }

    if (result != CHIP_NO_ERROR)
    {
        ChipLogProgress(DataManagement, "AccessControl: %s",
                        (result == CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL) ? "denied (restricted)" : "denied (restriction error)");
        return result;
    }

    return result;
}
#endif

#if CHIP_ACCESS_CONTROL_DUMP_ENABLED
CHIP_ERROR AccessControl::Dump(const Entry & entry)
{
    CHIP_ERROR err;

    ChipLogDetail(DataManagement, "----- BEGIN ENTRY -----");

    {
        FabricIndex fabricIndex;
        SuccessOrExit(err = entry.GetFabricIndex(fabricIndex));
        ChipLogDetail(DataManagement, "fabricIndex: %u", fabricIndex);
    }

    {
        Privilege privilege;
        SuccessOrExit(err = entry.GetPrivilege(privilege));
        ChipLogDetail(DataManagement, "privilege: %d", to_underlying(privilege));
    }

    {
        AuthMode authMode;
        SuccessOrExit(err = entry.GetAuthMode(authMode));
        ChipLogDetail(DataManagement, "authMode: %d", to_underlying(authMode));
    }

    {
        AuxiliaryType auxiliaryType;
        // Auxiliary type is optional, so it not being implemented
        // is still a valid configuration, all other errors should
        // be handled appropriately.
        err = GetAuxiliaryType(auxiliaryType);
        if (err != CHIP_ERROR_NOT_IMPLEMENTED)
        {
            SuccessOrExit(err);
            ChipLogDetail(DataManagement, "auxiliaryType: %d", to_underlying(auxiliaryType));
        }
    }

    {
        size_t count;
        SuccessOrExit(err = entry.GetSubjectCount(count));
        if (count)
        {
            ChipLogDetail(DataManagement, "subjects: %u", static_cast<unsigned>(count));
            for (size_t i = 0; i < count; ++i)
            {
                NodeId subject;
                SuccessOrExit(err = entry.GetSubject(i, subject));
                ChipLogDetail(DataManagement, "  %u: 0x" ChipLogFormatX64, static_cast<unsigned>(i), ChipLogValueX64(subject));
            }
        }
    }

    {
        size_t count;
        SuccessOrExit(err = entry.GetTargetCount(count));
        if (count)
        {
            ChipLogDetail(DataManagement, "targets: %u", static_cast<unsigned>(count));
            for (size_t i = 0; i < count; ++i)
            {
                Entry::Target target;
                SuccessOrExit(err = entry.GetTarget(i, target));
                if (target.flags & Entry::Target::kCluster)
                {
                    ChipLogDetail(DataManagement, "  %u: cluster: 0x" ChipLogFormatMEI, static_cast<unsigned>(i),
                                  ChipLogValueMEI(target.cluster));
                }
                if (target.flags & Entry::Target::kEndpoint)
                {
                    ChipLogDetail(DataManagement, "  %u: endpoint: %u", static_cast<unsigned>(i), target.endpoint);
                }
                if (target.flags & Entry::Target::kDeviceType)
                {
                    ChipLogDetail(DataManagement, "  %u: deviceType: 0x" ChipLogFormatMEI, static_cast<unsigned>(i),
                                  ChipLogValueMEI(target.deviceType));
                }
            }
        }
    }

    ChipLogDetail(DataManagement, "----- END ENTRY -----");

    return CHIP_NO_ERROR;

exit:
    ChipLogError(DataManagement, "AccessControl: dump failed %" CHIP_ERROR_FORMAT, err.Format());
    return err;
}
#endif

bool AccessControl::Entry::IsValid() const
{
    const char * log = "unexpected error";
    IgnoreUnusedVariable(log); // logging may be disabled

    AuthMode authMode           = AuthMode::kNone;
    FabricIndex fabricIndex     = kUndefinedFabricIndex;
    Privilege privilege         = static_cast<Privilege>(0);
    AuxiliaryType auxiliaryType = AuxiliaryType::kSystem;
    size_t subjectCount         = 0;
    size_t targetCount          = 0;

    CHIP_ERROR err = CHIP_NO_ERROR;
    SuccessOrExit(err = GetAuthMode(authMode));
    SuccessOrExit(err = GetFabricIndex(fabricIndex));
    SuccessOrExit(err = GetPrivilege(privilege));
    SuccessOrExit(err = GetSubjectCount(subjectCount));
    SuccessOrExit(err = GetTargetCount(targetCount));

    // Auxiliary type is optional, so it not being implemented
    // is still a valid configuration, all other errors should
    // be handled appropriately.
    err = GetAuxiliaryType(auxiliaryType);
    if (err != CHIP_ERROR_NOT_IMPLEMENTED)
    {
        SuccessOrExit(err);
    }

#if CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
    ChipLogProgress(DataManagement, "AccessControl: validating f=%u p=%c a=%c x=%d s=%d t=%d", fabricIndex,
                    GetPrivilegeStringForLogging(privilege), GetAuthModeStringForLogging(authMode),
                    GetAuxiliaryTypeStringForLogging(auxiliaryType), static_cast<int>(subjectCount), static_cast<int>(targetCount));
#endif // CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1

    // Fabric index must be defined.
    VerifyOrExit(fabricIndex != kUndefinedFabricIndex, log = "invalid fabric index");

    if (authMode != AuthMode::kCase)
    {
        // Operational PASE not supported for v1.0 (so must be group).
        VerifyOrExit(authMode == AuthMode::kGroup, log = "invalid auth mode");

        // Privilege must not be administer.
        VerifyOrExit(privilege != Privilege::kAdminister, log = "invalid privilege");
    }

    for (size_t i = 0; i < subjectCount; ++i)
    {
        NodeId subject;
        SuccessOrExit(err = GetSubject(i, subject));
        const bool kIsCase  = authMode == AuthMode::kCase;
        const bool kIsGroup = authMode == AuthMode::kGroup;
#if CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
        ChipLogProgress(DataManagement, "  validating subject 0x" ChipLogFormatX64, ChipLogValueX64(subject));
#endif // CHIP_CONFIG_ACCESS_CONTROL_POLICY_LOGGING_VERBOSITY > 1
        VerifyOrExit((kIsCase && IsValidCaseNodeId(subject)) || (kIsGroup && IsValidGroupNodeId(subject)), log = "invalid subject");
    }

    for (size_t i = 0; i < targetCount; ++i)
    {
        Entry::Target target;
        SuccessOrExit(err = GetTarget(i, target));
        const bool kHasCluster    = target.flags & Entry::Target::kCluster;
        const bool kHasEndpoint   = target.flags & Entry::Target::kEndpoint;
        const bool kHasDeviceType = target.flags & Entry::Target::kDeviceType;
        VerifyOrExit((kHasCluster || kHasEndpoint || kHasDeviceType) && !(kHasEndpoint && kHasDeviceType) &&
                         (!kHasCluster || IsValidClusterId(target.cluster)) &&
                         (!kHasEndpoint || IsValidEndpointId(target.endpoint)) &&
                         (!kHasDeviceType || IsValidDeviceTypeId(target.deviceType)),
                     log = "invalid target");
    }

    return true;

exit:
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(DataManagement, "AccessControl: %s %" CHIP_ERROR_FORMAT, log, err.Format());
    }
    else
    {
        ChipLogError(DataManagement, "AccessControl: %s", log);
    }
    return false;
}

void AccessControl::NotifyEntryChanged(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index,
                                       const Entry * entry, EntryListener::ChangeType changeType)
{
    for (EntryListener * listener = mEntryListener; listener != nullptr; listener = listener->mNext)
    {
        listener->OnEntryChanged(subjectDescriptor, fabric, index, entry, changeType);
    }
}

AccessControl & GetAccessControl()
{
    return (globalAccessControl) ? *globalAccessControl : defaultAccessControl.get();
}

void SetAccessControl(AccessControl & accessControl)
{
    ChipLogProgress(DataManagement, "AccessControl: setting");
    globalAccessControl = &accessControl;
}

void ResetAccessControlToDefault()
{
    globalAccessControl = nullptr;
}

} // namespace Access
} // namespace chip
