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

#include "AccessControl.h"

namespace {

using chip::FabricIndex;
using namespace chip::Access;

// Avoid GetAccessControl returning nullptr before SetAccessControl is called.
class UnimplementedDataProvider : public AccessControlDataProvider
{
    CHIP_ERROR Init() override { return CHIP_NO_ERROR; }

    void Finish() override {}

    EntryIterator * Entries() const override { return nullptr; }

    EntryIterator * Entries(FabricIndex fabricIndex) const override { return nullptr; }
};

// Avoid GetAccessControl returning nullptr before SetAccessControl is called.
UnimplementedDataProvider gUnimplementedDataProvider;
AccessControl gUnimplementedAccessControl(gUnimplementedDataProvider);

AccessControl * gAccessControl = &gUnimplementedAccessControl;

} // namespace

namespace chip {
namespace Access {

CHIP_ERROR AccessControl::Init()
{
    ChipLogDetail(DataManagement, "access control: initializing");
    // ...
    return CHIP_NO_ERROR;
}

void AccessControl::Finish()
{
    ChipLogDetail(DataManagement, "access control: finishing");
    // ...
}

CHIP_ERROR AccessControl::Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege privilege)
{
    CHIP_ERROR err = CHIP_ERROR_ACCESS_DENIED;

    EntryIterator * iterator = mDataProvider.Entries(subjectDescriptor.fabricIndex);
    // TODO: check error (but can't until we have an implementation)
#if 0
    ReturnErrorCodeIf(iterator == nullptr, CHIP_ERROR_INTERNAL);
#else
    ReturnErrorCodeIf(iterator == nullptr, CHIP_NO_ERROR);
#endif

    // TODO: a few more cases (PASE commissioning, CASE Authenticated Tags, etc.)

    while (auto entry = iterator->Next())
    {
        ChipLogDetail(DataManagement, "Checking entry");

        if (!entry->MatchesPrivilege(privilege))
            continue;
        ChipLogDetail(DataManagement, "  --> matched privilege");
        if (!entry->MatchesAuthMode(subjectDescriptor.authMode))
            continue;
        ChipLogDetail(DataManagement, "  --> matched authmode");
        if (!entry->MatchesSubject(subjectDescriptor.subjects[0]))
            continue;
        ChipLogDetail(DataManagement, "  --> matched subject");
        if (!entry->MatchesTarget(requestPath.endpoint, requestPath.cluster))
            continue;
        ChipLogDetail(DataManagement, "  --> matched target");

        err = CHIP_NO_ERROR;
        break;
    }

    iterator->Release();
    return err;
}

AccessControl * GetAccessControl()
{
    return gAccessControl;
}

void SetAccessControl(AccessControl * accessControl)
{
    if (accessControl != nullptr)
    {
        gAccessControl = accessControl;
    }
}

} // namespace Access
} // namespace chip
