/*
 *    Copyright (c) 2022 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 the CHIP CASE Session object that provides
 *      APIs for constructing a secure session using a certificate from the device's
 *      operational credentials.
 */

#pragma once

#include <lib/core/CHIPTLV.h>
#include <lib/support/DefaultStorageKeyAllocator.h>
#include <protocols/secure_channel/DefaultSessionResumptionStorage.h>

namespace chip {

/**
 * An example SessionResumptionStorage using PersistentStorageDelegate as it backend.
 */
class SimpleSessionResumptionStorage : public DefaultSessionResumptionStorage
{
public:
    CHIP_ERROR Init(PersistentStorageDelegate * storage)
    {
        VerifyOrReturnError(storage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
        mStorage = storage;
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR SaveIndex(const SessionIndex & index) override;
    CHIP_ERROR LoadIndex(SessionIndex & index) override;

    CHIP_ERROR SaveLink(ConstResumptionIdView resumptionId, const ScopedNodeId & node) override;
    CHIP_ERROR LoadLink(ConstResumptionIdView resumptionId, ScopedNodeId & node) override;
    CHIP_ERROR DeleteLink(ConstResumptionIdView resumptionId) override;

    CHIP_ERROR SaveState(const ScopedNodeId & node, ConstResumptionIdView resumptionId,
                         const Crypto::P256ECDHDerivedSecret & sharedSecret, const CATValues & peerCATs) override;
    CHIP_ERROR LoadState(const ScopedNodeId & node, ResumptionIdStorage & resumptionId,
                         Crypto::P256ECDHDerivedSecret & sharedSecret, CATValues & peerCATs) override;
    CHIP_ERROR DeleteState(const ScopedNodeId & node) override;

private:
    static const char * StorageKey(DefaultStorageKeyAllocator & keyAlloc, const ScopedNodeId & node);
    static const char * StorageKey(DefaultStorageKeyAllocator & keyAlloc, ConstResumptionIdView resumptionId);

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

    static constexpr size_t MaxIndexSize()
    {
        // The max size of the list is (1 byte control + bytes for actual value) times max number of list items
        return TLV::EstimateStructOverhead((1 + MaxScopedNodeIdSize()) * CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE);
    }

    static constexpr size_t MaxStateSize()
    {
        return TLV::EstimateStructOverhead(kResumptionIdSize, Crypto::P256ECDHDerivedSecret::Capacity(),
                                           CATValues::kSerializedLength);
    }

    static constexpr TLV::Tag kFabricIndexTag  = TLV::ContextTag(1);
    static constexpr TLV::Tag kPeerNodeIdTag   = TLV::ContextTag(2);
    static constexpr TLV::Tag kResumptionIdTag = TLV::ContextTag(3);
    static constexpr TLV::Tag kSharedSecretTag = TLV::ContextTag(4);
    static constexpr TLV::Tag kCATTag          = TLV::ContextTag(5);

    PersistentStorageDelegate * mStorage;
};

} // namespace chip
