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

#include "CastingStore.h"

#include <lib/core/TLV.h>
#include <platform/KeyValueStoreManager.h>

namespace matter {
namespace casting {
namespace support {

CastingStore * CastingStore::_CastingStore = nullptr;

CastingStore::CastingStore() {}

CastingStore * CastingStore::GetInstance()
{
    if (_CastingStore == nullptr)
    {
        _CastingStore = new CastingStore();
    }
    return _CastingStore;
}

CHIP_ERROR CastingStore::AddOrUpdate(core::CastingPlayer castingPlayer)
{
    ChipLogProgress(AppServer, "CastingStore::AddOrUpdate");

    // Read cache of CastingPlayers
    std::vector<core::CastingPlayer> castingPlayers = ReadAll();

    // search for castingPlayer in CastingStore cache and overwrite it, if found
    if (castingPlayers.size() != 0)
    {
        auto it = std::find_if(
            castingPlayers.begin(), castingPlayers.end(),
            [castingPlayer](const core::CastingPlayer & castingPlayerParam) { return castingPlayerParam == castingPlayer; });

        if (it != castingPlayers.end())
        {
            unsigned index        = (unsigned int) std::distance(castingPlayers.begin(), it);
            castingPlayers[index] = castingPlayer;
            ChipLogProgress(AppServer, "CastingStore::AddOrUpdate updating CastingPlayer in CastingStore cache");
            return WriteAll(castingPlayers); // return early
        }
    }

    // add *new* castingPlayer to CastingStore cache
    castingPlayers.push_back(castingPlayer);
    ChipLogProgress(AppServer, "CastingStore::AddOrUpdate adding new CastingPlayer in CastingStore cache");
    return WriteAll(castingPlayers);
}

std::vector<core::CastingPlayer> CastingStore::ReadAll()
{
    ChipLogProgress(AppServer, "CastingStore::ReadAll called");
    CHIP_ERROR err = CHIP_NO_ERROR;

    std::vector<core::CastingPlayer> castingPlayers;
    uint8_t castingStoreData[kCastingStoreDataMaxBytes];
    size_t castingStoreDataSize = 0;
    err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Get(kCastingStoreDataKey, castingStoreData,
                                                                      kCastingStoreDataMaxBytes, &castingStoreDataSize);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "KeyValueStoreMgr.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
    ChipLogProgress(AppServer, "CastingStore::ReadAll Read TLV(CastingStoreData) from KVS store with size: %lu bytes",
                    static_cast<unsigned long>(castingStoreDataSize));

    chip::TLV::TLVReader reader;
    reader.Init(castingStoreData);

    // read the envelope (and version)
    err = reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag());
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));

    chip::TLV::TLVType outerContainerType;
    err = reader.EnterContainer(outerContainerType);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

    err = reader.Next();
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
    chip::TLV::Tag outerContainerTag = reader.GetTag();
    uint8_t outerContainerTagNum     = static_cast<uint8_t>(chip::TLV::TagNumFromTag(outerContainerTag));
    VerifyOrReturnValue(outerContainerTagNum == kCastingStoreDataVersionTag, castingPlayers,
                        ChipLogError(AppServer, "CastingStoreDataVersionTag not found"));
    uint32_t version;
    err = reader.Get(version);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
    ChipLogProgress(AppServer, "CastingStore::ReadAll TLV(CastingStoreData) version: %d", version);

    // Entering CastingPlayers container
    err = reader.Next();
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.Next failed %" CHIP_ERROR_FORMAT, err.Format()));
    chip::TLV::TLVType castingPlayersContainerType;
    err = reader.EnterContainer(castingPlayersContainerType);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
    while ((err = reader.Next()) == CHIP_NO_ERROR)
    {
        // Entering CastingPlayer container
        chip::TLV::TLVType castingPlayerContainerType;
        err = reader.EnterContainer(castingPlayerContainerType);
        VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                            ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

        core::CastingPlayerAttributes attributes;
        std::vector<core::EndpointAttributes> endpointAttributesList;
        std::map<chip::EndpointId, std::vector<chip::ClusterId>> endpointServerListMap;
        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            chip::TLV::Tag castingPlayerContainerTag = reader.GetTag();
            VerifyOrReturnValue(chip::TLV::IsContextTag(castingPlayerContainerTag), std::vector<core::CastingPlayer>(),
                                ChipLogError(AppServer, "Unexpected non-context TLV tag"));

            uint8_t castingPlayerContainerTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(castingPlayerContainerTag));
            if (castingPlayerContainerTagNum == kCastingPlayerIdTag)
            {
                err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.id), core::kIdMaxLength + 1);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerNodeIdTag)
            {
                err = reader.Get(attributes.nodeId);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerFabricIndexTag)
            {
                err = reader.Get(attributes.fabricIndex);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerVendorIdTag)
            {
                err = reader.Get(attributes.vendorId);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerProductIdTag)
            {
                err = reader.Get(attributes.productId);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerDeviceTypeIdTag)
            {
                err = reader.Get(attributes.deviceType);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerSupportsCommissionerGeneratedPasscodeTag)
            {
                err = reader.Get(attributes.supportsCommissionerGeneratedPasscode);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerPortTag)
            {
                err = reader.Get(attributes.port);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerInstanceNameTag)
            {
                err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.instanceName),
                                      chip::Dnssd::Commission::kInstanceNameMaxLength + 1);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerDeviceNameTag)
            {
                err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.deviceName), chip::Dnssd::kMaxDeviceNameLen + 1);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerHostNameTag)
            {
                err = reader.GetBytes(reinterpret_cast<uint8_t *>(attributes.hostName), chip::Dnssd::kHostNameMaxLength + 1);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.GetBytes failed %" CHIP_ERROR_FORMAT, err.Format()));
                continue;
            }

            if (castingPlayerContainerTagNum == kCastingPlayerEndpointsContainerTag)
            {
                // Entering Endpoints container
                chip::TLV::TLVType endpointsContainerType;
                err = reader.EnterContainer(endpointsContainerType);
                VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
                core::EndpointAttributes endpointAttributes;
                std::vector<chip::ClusterId> serverList;
                while ((err = reader.Next()) == CHIP_NO_ERROR)
                {
                    // Entering Endpoint container
                    chip::TLV::TLVType endpointContainerType;
                    err = reader.EnterContainer(endpointContainerType);
                    VerifyOrReturnValue(
                        err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                    while ((err = reader.Next()) == CHIP_NO_ERROR)
                    {
                        chip::TLV::Tag endpointContainerTag = reader.GetTag();
                        VerifyOrReturnValue(chip::TLV::IsContextTag(endpointContainerTag), std::vector<core::CastingPlayer>(),
                                            ChipLogError(AppServer, "Unexpected non-context TLV tag"));

                        uint8_t endpointContainerTagNum = static_cast<uint8_t>(chip::TLV::TagNumFromTag(endpointContainerTag));
                        if (endpointContainerTagNum == kCastingPlayerEndpointIdTag)
                        {
                            err = reader.Get(endpointAttributes.mId);
                            VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                                ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                            continue;
                        }

                        if (endpointContainerTagNum == kCastingPlayerEndpointVendorIdTag)
                        {
                            err = reader.Get(endpointAttributes.mVendorId);
                            VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                                ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                            continue;
                        }

                        if (endpointContainerTagNum == kCastingPlayerEndpointProductIdTag)
                        {
                            err = reader.Get(endpointAttributes.mProductId);
                            VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                                ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                            continue;
                        }

                        std::vector<chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType> deviceTypeList;
                        if (endpointContainerTagNum == kCastingPlayerEndpointDeviceTypeListContainerTag)
                        {
                            // Entering DeviceTypeList container
                            chip::TLV::TLVType deviceTypeListContainerType;
                            err = reader.EnterContainer(deviceTypeListContainerType);
                            VerifyOrReturnValue(
                                err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                            while ((err = reader.Next()) == CHIP_NO_ERROR)
                            {
                                // Entering DeviceTypeStruct container
                                chip::TLV::TLVType deviceTypeStructContainerType;
                                err = reader.EnterContainer(deviceTypeStructContainerType);
                                VerifyOrReturnValue(
                                    err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                                chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType deviceTypeStruct;
                                while ((err = reader.Next()) == CHIP_NO_ERROR)
                                {
                                    chip::TLV::Tag deviceTypeStructContainerTag = reader.GetTag();
                                    VerifyOrReturnValue(chip::TLV::IsContextTag(deviceTypeStructContainerTag),
                                                        std::vector<core::CastingPlayer>(),
                                                        ChipLogError(AppServer, "Unexpected non-context TLV tag"));

                                    uint8_t deviceTypeStructContainerTagNum =
                                        static_cast<uint8_t>(chip::TLV::TagNumFromTag(deviceTypeStructContainerTag));
                                    if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeTag)
                                    {
                                        err = reader.Get(deviceTypeStruct.deviceType);
                                        VerifyOrReturnValue(
                                            err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                            ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                                        continue;
                                    }

                                    if (deviceTypeStructContainerTagNum == kCastingPlayerEndpointDeviceTypeRevisionTag)
                                    {
                                        err = reader.Get(deviceTypeStruct.revision);
                                        VerifyOrReturnValue(
                                            err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                            ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                                        continue;
                                    }
                                }

                                if (err == CHIP_END_OF_TLV)
                                {
                                    // Exiting DeviceTypeStruct container
                                    err = reader.ExitContainer(deviceTypeStructContainerType);
                                    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                                        ChipLogError(AppServer,
                                                                     "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT,
                                                                     err.Format()));

                                    deviceTypeList.push_back(deviceTypeStruct);
                                    continue;
                                }
                            }
                            if (err == CHIP_END_OF_TLV)
                            {
                                // Exiting DeviceTypeList container
                                err = reader.ExitContainer(deviceTypeListContainerType);
                                VerifyOrReturnValue(
                                    err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                                endpointAttributes.mDeviceTypeList = deviceTypeList;
                                continue;
                            }
                        }

                        if (endpointContainerTagNum == kCastingPlayerEndpointServerListContainerTag)
                        {
                            // Entering ServerList container
                            chip::TLV::TLVType serverListContainerType;
                            err = reader.EnterContainer(serverListContainerType);
                            VerifyOrReturnValue(
                                err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                ChipLogError(AppServer, "TLVReader.EnterContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                            while ((err = reader.Next()) == CHIP_NO_ERROR)
                            {
                                chip::TLV::Tag serverListContainerTag = reader.GetTag();
                                VerifyOrReturnValue(chip::TLV::IsContextTag(serverListContainerTag),
                                                    std::vector<core::CastingPlayer>(),
                                                    ChipLogError(AppServer, "Unexpected non-context TLV tag"));

                                uint8_t serverListContainerTagNum =
                                    static_cast<uint8_t>(chip::TLV::TagNumFromTag(serverListContainerTag));
                                if (serverListContainerTagNum == kCastingPlayerEndpointServerClusterIdTag)
                                {
                                    chip::ClusterId clusterId;
                                    err = reader.Get(clusterId);
                                    VerifyOrReturnValue(
                                        err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                        ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
                                    serverList.push_back(clusterId);
                                    continue;
                                }
                            }

                            if (err == CHIP_END_OF_TLV)
                            {
                                // Exiting ServerList container
                                err = reader.ExitContainer(serverListContainerType);
                                VerifyOrReturnValue(
                                    err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                    ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
                                continue;
                            }
                        }
                    }

                    if (err == CHIP_END_OF_TLV)
                    {
                        // Exiting Endpoint container
                        err = reader.ExitContainer(endpointContainerType);
                        VerifyOrReturnValue(
                            err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                            ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

                        endpointAttributesList.push_back(endpointAttributes);
                        endpointServerListMap[endpointAttributes.mId] = serverList;
                        serverList.clear();
                        continue;
                    }
                }

                if (err == CHIP_END_OF_TLV)
                {
                    // Exiting Endpoints container
                    err = reader.ExitContainer(endpointsContainerType);
                    VerifyOrReturnValue(
                        err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
                    continue;
                }
            }
        }
        if (err == CHIP_END_OF_TLV)
        {
            // Exiting CastingPlayer container
            err = reader.ExitContainer(castingPlayerContainerType);
            VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                                ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

            // create a castingPlayer with Endpoints and add it to the castingPlayers to be returned
            core::CastingPlayer castingPlayer(attributes);
            for (auto & endpointAttributes : endpointAttributesList)
            {
                std::shared_ptr<core::Endpoint> endpoint(new core::Endpoint(&castingPlayer, endpointAttributes));
                endpoint->RegisterClusters(endpointServerListMap[endpointAttributes.mId]);
                castingPlayer.RegisterEndpoint(endpoint);
            }
            castingPlayers.push_back(castingPlayer);
            continue;
        }
    }

    VerifyOrReturnValue(err == CHIP_END_OF_TLV, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLV parsing failed %" CHIP_ERROR_FORMAT, err.Format()));

    err = reader.ExitContainer(castingPlayersContainerType);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

    err = reader.ExitContainer(outerContainerType);
    VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector<core::CastingPlayer>(),
                        ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));

    ChipLogProgress(AppServer, "CastingStore::ReadAll CastingPlayers size: %lu", static_cast<unsigned long>(castingPlayers.size()));
    return castingPlayers;
}

CHIP_ERROR CastingStore::WriteAll(std::vector<core::CastingPlayer> castingPlayers)
{
    ChipLogProgress(AppServer, "CastingStore::WriteAll called");

    chip::TLV::TLVWriter tlvWriter;
    uint8_t castingStoreData[kCastingStoreDataMaxBytes];
    tlvWriter.Init(castingStoreData, kCastingStoreDataMaxBytes);

    chip::TLV::TLVType outerContainerType;
    ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, outerContainerType));
    ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingStoreDataVersionTag), kCurrentCastingStoreDataVersion));

    chip::TLV::TLVType castingPlayersContainerType;
    // CastingPlayers container starts
    ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayersContainerTag), chip::TLV::kTLVType_Array,
                                                  castingPlayersContainerType));

    for (auto & castingPlayer : castingPlayers)
    {
        chip::TLV::TLVType castingPlayerContainerType;
        // CastingPlayer container starts
        ReturnErrorOnFailure(
            tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, castingPlayerContainerType));

        ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerIdTag), (const uint8_t *) castingPlayer.GetId(),
                                                static_cast<uint32_t>(strlen(castingPlayer.GetId()) + 1)));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerNodeIdTag), castingPlayer.GetNodeId()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerFabricIndexTag), castingPlayer.GetFabricIndex()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerVendorIdTag), castingPlayer.GetVendorId()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerProductIdTag), castingPlayer.GetProductId()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerDeviceTypeIdTag), castingPlayer.GetDeviceType()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerSupportsCommissionerGeneratedPasscodeTag),
                                           castingPlayer.GetSupportsCommissionerGeneratedPasscode()));
        ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerPortTag), castingPlayer.GetPort()));
        ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerInstanceNameTag),
                                                (const uint8_t *) castingPlayer.GetInstanceName(),
                                                static_cast<uint32_t>(strlen(castingPlayer.GetInstanceName()) + 1)));
        ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerDeviceNameTag),
                                                (const uint8_t *) castingPlayer.GetDeviceName(),
                                                static_cast<uint32_t>(strlen(castingPlayer.GetDeviceName()) + 1)));
        ReturnErrorOnFailure(tlvWriter.PutBytes(chip::TLV::ContextTag(kCastingPlayerHostNameTag),
                                                (const uint8_t *) castingPlayer.GetHostName(),
                                                static_cast<uint32_t>(strlen(castingPlayer.GetHostName()) + 1)));

        // Endpoints container starts
        chip::TLV::TLVType endpointsContainerType;
        ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointsContainerTag),
                                                      chip::TLV::kTLVType_Array, endpointsContainerType));
        std::vector<memory::Strong<core::Endpoint>> endpoints = core::CastingPlayer::GetTargetCastingPlayer()->GetEndpoints();
        for (auto & endpoint : endpoints)
        {
            chip::TLV::TLVType endpointContainerType;
            // Endpoint container starts
            ReturnErrorOnFailure(
                tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure, endpointContainerType));
            ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointIdTag), endpoint->GetId()));
            ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointVendorIdTag), endpoint->GetVendorId()));
            ReturnErrorOnFailure(
                tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointProductIdTag), endpoint->GetProductId()));

            // DeviceTypeList container starts
            chip::TLV::TLVType deviceTypeListContainerType;
            ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeListContainerTag),
                                                          chip::TLV::kTLVType_Array, deviceTypeListContainerType));
            std::vector<chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType> deviceTypeList =
                endpoint->GetDeviceTypeList();
            for (chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType deviceTypeStruct : deviceTypeList)
            {
                chip::TLV::TLVType deviceTypeStructContainerType;
                // DeviceTypeStruct container starts
                ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::AnonymousTag(), chip::TLV::kTLVType_Structure,
                                                              deviceTypeStructContainerType));
                ReturnErrorOnFailure(
                    tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeTag), deviceTypeStruct.deviceType));
                ReturnErrorOnFailure(
                    tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointDeviceTypeRevisionTag), deviceTypeStruct.revision));

                // DeviceTypeStruct container ends
                ReturnErrorOnFailure(tlvWriter.EndContainer(deviceTypeStructContainerType));
            }
            // DeviceTypeList container ends
            ReturnErrorOnFailure(tlvWriter.EndContainer(deviceTypeListContainerType));

            // ServerList container starts
            chip::TLV::TLVType serverListContainerType;
            ReturnErrorOnFailure(tlvWriter.StartContainer(chip::TLV::ContextTag(kCastingPlayerEndpointServerListContainerTag),
                                                          chip::TLV::kTLVType_Structure, serverListContainerType));
            std::vector<chip::ClusterId> serverList = endpoint->GetServerList();
            for (chip::ClusterId clusterId : serverList)
            {
                ReturnErrorOnFailure(tlvWriter.Put(chip::TLV::ContextTag(kCastingPlayerEndpointServerClusterIdTag), clusterId));
            }
            // ServerList container ends
            ReturnErrorOnFailure(tlvWriter.EndContainer(serverListContainerType));

            // Endpoint container ends
            ReturnErrorOnFailure(tlvWriter.EndContainer(endpointContainerType));
        }
        // Endpoints container ends
        ReturnErrorOnFailure(tlvWriter.EndContainer(endpointsContainerType));

        // CastingPlayer container ends
        ReturnErrorOnFailure(tlvWriter.EndContainer(castingPlayerContainerType));
    }

    // CastingPlayers container ends
    ReturnErrorOnFailure(tlvWriter.EndContainer(castingPlayersContainerType));
    ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType));

    ReturnErrorOnFailure(tlvWriter.Finalize());
    ChipLogProgress(AppServer,
                    "CastingStore::WriteAll TLV(CastingStoreData).LengthWritten: %d bytes, CastingPlayers size: %lu "
                    "and version: %d",
                    tlvWriter.GetLengthWritten(), static_cast<unsigned long>(castingPlayers.size()),
                    kCurrentCastingStoreDataVersion);
    return chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Put(kCastingStoreDataKey, castingStoreData,
                                                                       tlvWriter.GetLengthWritten());
}

CHIP_ERROR CastingStore::DeleteAll()
{
    ChipLogProgress(AppServer, "CastingStore::DeleteAll called");
    CHIP_ERROR err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr().Delete(kCastingStoreDataKey);
    if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) // no error, if the key-value pair was not stored
    {
        ChipLogProgress(AppServer, "CastingStore::DeleteAll ignoring error %" CHIP_ERROR_FORMAT, err.Format());
        return CHIP_NO_ERROR;
    }
    return err;
}

CHIP_ERROR CastingStore::Delete(core::CastingPlayer castingPlayer)
{
    ChipLogProgress(AppServer, "CastingStore::Delete");

    // Read cache of CastingPlayers
    std::vector<core::CastingPlayer> castingPlayers = ReadAll();

    // search for castingPlayer in CastingStore cache and delete it, if found
    if (castingPlayers.size() != 0)
    {
        auto it = std::find_if(
            castingPlayers.begin(), castingPlayers.end(),
            [castingPlayer](const core::CastingPlayer & castingPlayerParam) { return castingPlayerParam == castingPlayer; });

        if (it != castingPlayers.end())
        {
            ChipLogProgress(AppServer, "CastingStore::Delete deleting CastingPlayer %s from CastingStore cache", it->GetId());
            castingPlayers.erase(it);
            return WriteAll(castingPlayers);
        }
    }
    return CHIP_NO_ERROR;
}

void CastingStore::OnFabricRemoved(const chip::FabricTable & fabricTable, chip::FabricIndex fabricIndex)
{
    ChipLogProgress(AppServer, "CastingStore::OnFabricRemoved");

    // Read cache of CastingPlayers
    std::vector<core::CastingPlayer> castingPlayers = ReadAll();

    // search for castingPlayer in CastingStore cache and delete it, if found
    if (castingPlayers.size() != 0)
    {
        auto it = std::find_if(castingPlayers.begin(), castingPlayers.end(),
                               [fabricIndex](const core::CastingPlayer & castingPlayerParam) {
                                   return castingPlayerParam.GetFabricIndex() == fabricIndex;
                               });

        if (it != castingPlayers.end())
        {
            ChipLogProgress(AppServer, "CastingStore::OnFabricRemoved deleting CastingPlayer %s from CastingStore cache",
                            it->GetId());
            castingPlayers.erase(it);
            WriteAll(castingPlayers);
        }
    }
}

}; // namespace support
}; // namespace casting
}; // namespace matter
