/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <app/server/AclStorage.h>

#include <lib/support/DefaultStorageKeyAllocator.h>

using namespace chip;
using namespace chip::app;
using namespace chip::Access;

using Entry            = AccessControl::Entry;
using EntryListener    = AccessControl::EntryListener;
using StagingAuthMode  = Clusters::AccessControl::AccessControlEntryAuthModeEnum;
using StagingPrivilege = Clusters::AccessControl::AccessControlEntryPrivilegeEnum;
using StagingTarget    = Clusters::AccessControl::Structs::Target::Type;
using Target           = AccessControl::Entry::Target;

namespace {

struct StagingSubject
{
    NodeId nodeId;
    StagingAuthMode authMode;
};

CHIP_ERROR Convert(AuthMode from, StagingAuthMode & to)
{
    switch (from)
    {
    case AuthMode::kPase:
        to = StagingAuthMode::kPase;
        break;
    case AuthMode::kCase:
        to = StagingAuthMode::kCase;
        break;
    case AuthMode::kGroup:
        to = StagingAuthMode::kGroup;
        break;
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(StagingAuthMode from, AuthMode & to)
{
    switch (from)
    {
    case StagingAuthMode::kPase:
        to = AuthMode::kPase;
        break;
    case StagingAuthMode::kCase:
        to = AuthMode::kCase;
        break;
    case StagingAuthMode::kGroup:
        to = AuthMode::kGroup;
        break;
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(Privilege from, StagingPrivilege & to)
{
    switch (from)
    {
    case Privilege::kView:
        to = StagingPrivilege::kView;
        break;
    case Privilege::kProxyView:
        to = StagingPrivilege::kProxyView;
        break;
    case Privilege::kOperate:
        to = StagingPrivilege::kOperate;
        break;
    case Privilege::kManage:
        to = StagingPrivilege::kManage;
        break;
    case Privilege::kAdminister:
        to = StagingPrivilege::kAdminister;
        break;
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(StagingPrivilege from, Privilege & to)
{
    switch (from)
    {
    case StagingPrivilege::kView:
        to = Privilege::kView;
        break;
    case StagingPrivilege::kProxyView:
        to = Privilege::kProxyView;
        break;
    case StagingPrivilege::kOperate:
        to = Privilege::kOperate;
        break;
    case StagingPrivilege::kManage:
        to = Privilege::kManage;
        break;
    case StagingPrivilege::kAdminister:
        to = Privilege::kAdminister;
        break;
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(NodeId from, StagingSubject & to)
{
    if (IsOperationalNodeId(from) || IsCASEAuthTag(from))
    {
        to = { .nodeId = from, .authMode = StagingAuthMode::kCase };
    }
    else if (IsGroupId(from))
    {
        to = { .nodeId = GroupIdFromNodeId(from), .authMode = StagingAuthMode::kGroup };
    }
    else if (IsPAKEKeyId(from))
    {
        to = { .nodeId = PAKEKeyIdFromNodeId(from), .authMode = StagingAuthMode::kPase };
    }
    else
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(StagingSubject from, NodeId & to)
{
    switch (from.authMode)
    {
    case StagingAuthMode::kPase:
        ReturnErrorCodeIf((from.nodeId & ~kMaskPAKEKeyId) != 0, CHIP_ERROR_INVALID_ARGUMENT);
        to = NodeIdFromPAKEKeyId(static_cast<PasscodeId>(from.nodeId));
        break;
    case StagingAuthMode::kCase:
        to = from.nodeId;
        break;
    case StagingAuthMode::kGroup:
        ReturnErrorCodeIf((from.nodeId & ~kMaskGroupId) != 0, CHIP_ERROR_INVALID_ARGUMENT);
        to = NodeIdFromGroupId(static_cast<GroupId>(from.nodeId));
        break;
    default:
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(const Target & from, StagingTarget & to)
{
    if ((from.flags & Target::kCluster) != 0)
    {
        to.cluster.SetNonNull(from.cluster);
    }
    else
    {
        to.cluster.SetNull();
    }
    if ((from.flags & Target::kEndpoint) != 0)
    {
        to.endpoint.SetNonNull(from.endpoint);
    }
    else
    {
        to.endpoint.SetNull();
    }
    if ((from.flags & Target::kDeviceType) != 0)
    {
        to.deviceType.SetNonNull(from.deviceType);
    }
    else
    {
        to.deviceType.SetNull();
    }
    return CHIP_NO_ERROR;
}

CHIP_ERROR Convert(const StagingTarget & from, Target & to)
{
    to.flags = 0;
    if (!from.cluster.IsNull())
    {
        to.flags |= Target::kCluster;
        to.cluster = from.cluster.Value();
    }
    if (!from.endpoint.IsNull())
    {
        to.flags |= Target::kEndpoint;
        to.endpoint = from.endpoint.Value();
    }
    if (!from.deviceType.IsNull())
    {
        to.flags |= Target::kDeviceType;
        to.deviceType = from.deviceType.Value();
    }
    return CHIP_NO_ERROR;
}

} // namespace

namespace chip {
namespace app {

CHIP_ERROR AclStorage::DecodableEntry::Decode(TLV::TLVReader & reader)
{
    ReturnErrorOnFailure(mStagingEntry.Decode(reader));
    ReturnErrorOnFailure(Unstage());
    return CHIP_NO_ERROR;
}

CHIP_ERROR AclStorage::DecodableEntry::Unstage()
{
    ReturnErrorOnFailure(GetAccessControl().PrepareEntry(mEntry));

    ReturnErrorOnFailure(mEntry.SetFabricIndex(mStagingEntry.fabricIndex));

    {
        Privilege privilege;
        ReturnErrorOnFailure(Convert(mStagingEntry.privilege, privilege));
        ReturnErrorOnFailure(mEntry.SetPrivilege(privilege));
    }

    {
        AuthMode authMode;
        ReturnErrorOnFailure(Convert(mStagingEntry.authMode, authMode));
        ReturnErrorOnFailure(mEntry.SetAuthMode(authMode));
    }

    if (!mStagingEntry.subjects.IsNull())
    {
        auto iterator = mStagingEntry.subjects.Value().begin();
        while (iterator.Next())
        {
            StagingSubject tmp = { .nodeId = iterator.GetValue(), .authMode = mStagingEntry.authMode };
            NodeId subject;
            ReturnErrorOnFailure(Convert(tmp, subject));
            ReturnErrorOnFailure(mEntry.AddSubject(nullptr, subject));
        }
        ReturnErrorOnFailure(iterator.GetStatus());
    }

    if (!mStagingEntry.targets.IsNull())
    {
        auto iterator = mStagingEntry.targets.Value().begin();
        while (iterator.Next())
        {
            Target target;
            ReturnErrorOnFailure(Convert(iterator.GetValue(), target));
            ReturnErrorOnFailure(mEntry.AddTarget(nullptr, target));
        }
        ReturnErrorOnFailure(iterator.GetStatus());
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR AclStorage::EncodableEntry::EncodeForRead(TLV::TLVWriter & writer, TLV::Tag tag, FabricIndex fabric) const
{
    ReturnErrorOnFailure(Stage());
    ReturnErrorOnFailure(mStagingEntry.EncodeForRead(writer, tag, fabric));
    return CHIP_NO_ERROR;
}

CHIP_ERROR AclStorage::EncodableEntry::EncodeForWrite(TLV::TLVWriter & writer, TLV::Tag tag) const
{
    ReturnErrorOnFailure(Stage());
    ReturnErrorOnFailure(mStagingEntry.EncodeForWrite(writer, tag));
    return CHIP_NO_ERROR;
}

CHIP_ERROR AclStorage::EncodableEntry::Stage() const
{
    ReturnErrorOnFailure(mEntry.GetFabricIndex(mStagingEntry.fabricIndex));

    {
        Privilege privilege;
        ReturnErrorOnFailure(mEntry.GetPrivilege(privilege));
        ReturnErrorOnFailure(Convert(privilege, mStagingEntry.privilege));
    }

    {
        AuthMode authMode;
        ReturnErrorOnFailure(mEntry.GetAuthMode(authMode));
        ReturnErrorOnFailure(Convert(authMode, mStagingEntry.authMode));
    }

    {
        size_t count;
        ReturnErrorOnFailure(mEntry.GetSubjectCount(count));
        if (count > 0)
        {
            for (size_t i = 0; i < count; ++i)
            {
                NodeId subject;
                ReturnErrorOnFailure(mEntry.GetSubject(i, subject));
                StagingSubject tmp;
                ReturnErrorOnFailure(Convert(subject, tmp));
                mStagingSubjects[i] = tmp.nodeId;
            }
            mStagingEntry.subjects.SetNonNull(mStagingSubjects, count);
        }
        else
        {
            mStagingEntry.subjects.SetNull();
        }
    }

    {
        size_t count;
        ReturnErrorOnFailure(mEntry.GetTargetCount(count));
        if (count > 0)
        {
            for (size_t i = 0; i < count; ++i)
            {
                Target target;
                ReturnErrorOnFailure(mEntry.GetTarget(i, target));
                ReturnErrorOnFailure(Convert(target, mStagingTargets[i]));
            }
            mStagingEntry.targets.SetNonNull(mStagingTargets, count);
        }
        else
        {
            mStagingEntry.targets.SetNull();
        }
    }

    return CHIP_NO_ERROR;
}

} // namespace app
} // namespace chip
