/*
 *
 *    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 "static-supported-modes-manager.h"
#include <platform/ESP32/ESP32Config.h>

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::DeviceLayer::Internal;
using namespace chip::app::Clusters::ModeSelect;
using chip::Protocols::InteractionModel::Status;

using ModeOptionStructType = Structs::ModeOptionStruct::Type;
using SemanticTag          = Structs::SemanticTagStruct::Type;

template <typename T>
using List = app::DataModel::List<T>;

SupportedModesManager::ModeOptionsProvider * StaticSupportedModesManager::epModeOptionsProviderList = nullptr;

const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager();

int StaticSupportedModesManager::mSize = 0;

CHIP_ERROR StaticSupportedModesManager::InitEndpointArray(int size)
{
    if (epModeOptionsProviderList != nullptr)
    {
        ChipLogError(Zcl, "Cannot allocate epModeOptionsProviderList");
        return CHIP_ERROR_INCORRECT_STATE;
    }
    mSize                     = size;
    epModeOptionsProviderList = new SupportedModesManager::ModeOptionsProvider[mSize];
    if (epModeOptionsProviderList == nullptr)
    {
        ChipLogError(Zcl, "Failed to allocate memory to epModeOptionsProviderList");
        return CHIP_ERROR_NO_MEMORY;
    }
    for (int i = 0; i < mSize; i++)
    {
        epModeOptionsProviderList[i] = ModeOptionsProvider();
    }
    return CHIP_NO_ERROR;
}

SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const
{
    if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr)
    {
        return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end());
    }

    ModeOptionStructType * modeOptionStructList = nullptr;
    SemanticTag * semanticTags                  = nullptr;

    char keyBuf[ESP32Config::kMaxConfigKeyNameLength];
    uint32_t supportedModeCount = 0;

    VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR,
                        ModeOptionsProvider(nullptr, nullptr));
    ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
    VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR,
                        ModeOptionsProvider(nullptr, nullptr));

    modeOptionStructList = new ModeOptionStructType[supportedModeCount];
    if (modeOptionStructList == nullptr)
    {
        return ModeOptionsProvider(nullptr, nullptr);
    }

    epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount);

    for (int index = 0; index < supportedModeCount; index++)
    {
        Structs::ModeOptionStruct::Type option;
        uint32_t supportedModeMode = 0;
        uint32_t semanticTagCount  = 0;
        size_t outLen              = 0;

        memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
        VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) ==
                                CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
        ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
        VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

        char * modeLabel = new char[outLen + 1];
        if (modeLabel == nullptr)
        {
            CleanUp(endpointId);
            return ModeOptionsProvider(nullptr, nullptr);
        }

        VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

        memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
        VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) ==
                                CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
        ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
        VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

        memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
        VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) ==
                                CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
        ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
        VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR,
                            ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

        semanticTags = new SemanticTag[semanticTagCount];
        if (semanticTags == nullptr)
        {
            CleanUp(endpointId);
            return ModeOptionsProvider(nullptr, nullptr);
        }
        for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++)
        {

            uint32_t semanticTagValue   = 0;
            uint32_t semanticTagMfgCode = 0;
            SemanticTag tag;

            memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
            VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) ==
                                    CHIP_NO_ERROR,
                                ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
            ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
            VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR,
                                ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

            memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength);
            VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) ==
                                    CHIP_NO_ERROR,
                                ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));
            ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf);
            VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR,
                                ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId));

            tag.value             = static_cast<uint16_t>(semanticTagValue);
            tag.mfgCode           = static_cast<chip::VendorId>(semanticTagMfgCode);
            semanticTags[stIndex] = tag;
        }

        option.label        = chip::CharSpan::fromCharString(modeLabel);
        option.mode         = static_cast<uint8_t>(supportedModeMode);
        option.semanticTags = DataModel::List<const SemanticTag>(semanticTags, semanticTagCount);

        modeOptionStructList[index] = option;
    }

    return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount);
}

Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode,
                                                        const ModeOptionStructType ** dataPtr) const
{
    auto modeOptionsProvider = this->getModeOptionsProvider(endpointId);
    if (modeOptionsProvider.begin() == nullptr)
    {
        return Status::UnsupportedCluster;
    }
    auto * begin = modeOptionsProvider.begin();
    auto * end   = modeOptionsProvider.end();

    for (auto * it = begin; it != end; ++it)
    {
        auto & modeOption = *it;
        if (modeOption.mode == mode)
        {
            *dataPtr = &modeOption;
            return Status::Success;
        }
    }
    ChipLogProgress(Zcl, "Cannot find the mode %u", mode);
    return Status::InvalidCommand;
}

const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager()
{
    return &StaticSupportedModesManager::getStaticSupportedModesManagerInstance();
}

void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const
{
    if (epModeOptionsProviderList[endpointId].begin() != nullptr)
    {
        auto * begin = epModeOptionsProviderList[endpointId].begin();
        auto * end   = epModeOptionsProviderList[endpointId].end();
        for (auto * it = begin; it != end; ++it)
        {
            auto & modeOption = *it;
            delete[] modeOption.label.data();
            delete[] modeOption.semanticTags.data();
        }
        delete[] begin;
    }
    epModeOptionsProviderList[endpointId] = ModeOptionsProvider();
}

void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const
{
    ChipLogError(Zcl, "Supported mode data is in incorrect format");
    FreeSupportedModes(endpointId);
}
