/*
 *    Copyright (c) 2023 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.
 */

/**
 *    @file
 *      This file defines a basic implementation of SubscriptionResumptionStorage that
 *      persists subscriptions in a flat list in TLV.
 */

#pragma once

#include <app/SubscriptionResumptionStorage.h>

#include <lib/core/TLV.h>
#include <lib/support/DefaultStorageKeyAllocator.h>
#include <lib/support/Pool.h>

namespace chip {
namespace app {

/**
 * An example SubscriptionResumptionStorage using PersistentStorageDelegate as it backend.
 */
class SimpleSubscriptionResumptionStorage : public SubscriptionResumptionStorage
{
public:
    static constexpr size_t kIteratorsMax = CHIP_CONFIG_MAX_SUBSCRIPTION_RESUMPTION_STORAGE_CONCURRENT_ITERATORS;

    CHIP_ERROR Init(PersistentStorageDelegate * storage);

    SubscriptionInfoIterator * IterateSubscriptions() override;

    CHIP_ERROR Save(SubscriptionInfo & subscriptionInfo) override;

    CHIP_ERROR Delete(NodeId nodeId, FabricIndex fabricIndex, SubscriptionId subscriptionId) override;

    CHIP_ERROR DeleteAll(FabricIndex fabricIndex) override;

protected:
    CHIP_ERROR Save(TLV::TLVWriter & writer, SubscriptionInfo & subscriptionInfo);
    CHIP_ERROR Load(uint16_t subscriptionIndex, SubscriptionInfo & subscriptionInfo);
    CHIP_ERROR Delete(uint16_t subscriptionIndex);
    uint16_t Count();
    CHIP_ERROR DeleteMaxCount();

    class SimpleSubscriptionInfoIterator : public SubscriptionInfoIterator
    {
    public:
        SimpleSubscriptionInfoIterator(SimpleSubscriptionResumptionStorage & storage);
        size_t Count() override;
        bool Next(SubscriptionInfo & output) override;
        void Release() override;

    private:
        SimpleSubscriptionResumptionStorage & mStorage;
        uint16_t mNextIndex;
    };

    static constexpr size_t MaxScopedNodeIdSize() { return TLV::EstimateStructOverhead(sizeof(NodeId), sizeof(FabricIndex)); }

    static constexpr size_t MaxSubscriptionPathsSize()
    {
        // IM engine declares an attribute path pool and an event path pool, and each pool
        // includes CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS for subscriptions
        return 2 *
            TLV::EstimateStructOverhead(
                   TLV::EstimateStructOverhead(sizeof(uint8_t), sizeof(EndpointId), sizeof(ClusterId), sizeof(AttributeId)) *
                   // Constant product inside a CHIPConfig.h macro; cannot widen at the use site.
                   // NOLINTNEXTLINE(bugprone-implicit-widening-of-multiplication-result)
                   CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS);
    }

    static constexpr size_t MaxSubscriptionSize()
    {
        // All the fields added together
        return TLV::EstimateStructOverhead(MaxScopedNodeIdSize(), sizeof(SubscriptionId), sizeof(uint16_t), sizeof(uint16_t),
                                           sizeof(bool), MaxSubscriptionPathsSize());
    }

    enum class EventPathType : uint8_t
    {
        kUrgent    = 0x1,
        kNonUrgent = 0x2,
    };

    // Flat list of subscriptions indexed from from 0 to CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS-1
    //
    // Each entry in list is a Subscription TLV structure:
    //   Structure of: (Subscription info)
    //     Node ID
    //     Fabric Index
    //     Subscription ID
    //     Min interval
    //     Max interval
    //     Fabric filtered boolean
    //     List of:
    //       Structure of: (Attribute path)
    //         Endpoint ID
    //         Cluster ID
    //         Attribute ID
    //     List of:
    //       Structure of: (Event path)
    //         Event subscription type (urgent / non-urgent)
    //         Endpoint ID
    //         Cluster ID
    //         Event ID

    static constexpr TLV::Tag kPeerNodeIdTag         = TLV::ContextTag(1);
    static constexpr TLV::Tag kFabricIndexTag        = TLV::ContextTag(2);
    static constexpr TLV::Tag kSubscriptionIdTag     = TLV::ContextTag(3);
    static constexpr TLV::Tag kMinIntervalTag        = TLV::ContextTag(4);
    static constexpr TLV::Tag kMaxIntervalTag        = TLV::ContextTag(5);
    static constexpr TLV::Tag kFabricFilteredTag     = TLV::ContextTag(6);
    static constexpr TLV::Tag kAttributePathsListTag = TLV::ContextTag(7);
    static constexpr TLV::Tag kEventPathsListTag     = TLV::ContextTag(8);
    static constexpr TLV::Tag kAttributePathTag      = TLV::ContextTag(9);
    static constexpr TLV::Tag kEventPathTag          = TLV::ContextTag(10);
    static constexpr TLV::Tag kEndpointIdTag         = TLV::ContextTag(11);
    static constexpr TLV::Tag kClusterIdTag          = TLV::ContextTag(12);
    static constexpr TLV::Tag kAttributeIdTag        = TLV::ContextTag(13);
    static constexpr TLV::Tag kEventIdTag            = TLV::ContextTag(14);
    static constexpr TLV::Tag kEventPathTypeTag      = TLV::ContextTag(16);
    static constexpr TLV::Tag kResumptionRetriesTag  = TLV::ContextTag(17);

    PersistentStorageDelegate * mStorage;
    ObjectPool<SimpleSubscriptionInfoIterator, kIteratorsMax> mSubscriptionInfoIterators;
};
} // namespace app
} // namespace chip
