/**
 *
 *    Copyright (c) 2023 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/clusters/scenes-server/SceneTable.h>
#include <app/util/attribute-storage.h>
#include <app/util/types_stub.h>
#include <lib/core/DataModelTypes.h>

namespace chip {
namespace scenes {

/// @brief Default implementation of handler, handle EFS from add scene and view scene commands for any cluster
///        The implementation of SerializeSave and ApplyScene were omitted and must be implemented in a way that
///        is compatible with the SerializeAdd output in order to function with the Default Scene Handler.
///        It is worth noting that this implementation is very memory consuming. In the current worst case,
///        (Color control cluster), the Extension Field Set's value pair list TLV occupies 99 bytes of memory
class DefaultSceneHandlerImpl : public scenes::SceneHandler
{
    template <typename T>
    using List = app::DataModel::List<T>;

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

    using AttributeValuePairType          = app::Clusters::ScenesManagement::Structs::AttributeValuePair::Type;
    using AttributeValuePairDecodableType = app::Clusters::ScenesManagement::Structs::AttributeValuePair::DecodableType;
    using ExtensionFieldSetDecodableType  = app::Clusters::ScenesManagement::Structs::ExtensionFieldSet::DecodableType;
    using ExtensionFieldSetType           = app::Clusters::ScenesManagement::Structs::ExtensionFieldSet::Type;

public:
    /// @brief Struct meant to map the state of a cluster to a specific endpoint. Meant to be used to apply scenes using a timer for
    /// transitioning
    /// @tparam ValueType type of the value to map to the endpoint, must implement operator= and operator== for complex types
    template <typename ValueType>
    struct EndpointStatePair
    {
        EndpointStatePair(EndpointId endpoint = kInvalidEndpointId, ValueType value = ValueType{}) :
            mEndpoint(endpoint), mValue(value)
        {}
        EndpointId mEndpoint;
        ValueType mValue;
    };

    template <typename ValueType, size_t MaxEndpointCount>
    struct StatePairBuffer
    {
        static_assert(std::is_trivial<ValueType>::value, "ValueType must be trivial");
        static_assert(MaxEndpointCount < std::numeric_limits<uint16_t>::max(), "MaxEndpointCount must be less than 65535");

        bool IsEmpty() const { return (mPairCount == 0); }

        CHIP_ERROR FindPair(const EndpointId endpoint, uint16_t & found_index) const
        {
            VerifyOrReturnError(!IsEmpty(), CHIP_ERROR_NOT_FOUND);
            for (found_index = 0; found_index < mPairCount; found_index++)
            {
                if (endpoint == mStatePairBuffer[found_index].mEndpoint)
                {
                    return CHIP_NO_ERROR;
                }
            }

            return CHIP_ERROR_NOT_FOUND;
        }

        CHIP_ERROR InsertPair(const EndpointStatePair<ValueType> & status)
        {
            uint16_t idx;
            CHIP_ERROR err = FindPair(status.mEndpoint, idx);

            if (CHIP_NO_ERROR == err)
            {
                mStatePairBuffer[idx] = status;
            }
            else if (mPairCount < MaxEndpointCount)
            {
                // If not found, insert at the end
                mStatePairBuffer[mPairCount] = status;
                mPairCount++;
            }
            else
            {
                return CHIP_ERROR_NO_MEMORY;
            }

            return CHIP_NO_ERROR;
        }

        CHIP_ERROR GetPair(const EndpointId endpoint, EndpointStatePair<ValueType> & status) const
        {
            uint16_t idx;
            ReturnErrorOnFailure(FindPair(endpoint, idx));

            status = mStatePairBuffer[idx];
            return CHIP_NO_ERROR;
        }

        /// @brief Removes Pair and decrements Pair count if the endpoint existed in the array
        /// @param endpoint : endpoint id of the pair
        CHIP_ERROR RemovePair(const EndpointId endpoint)
        {
            uint16_t position;
            VerifyOrReturnValue(CHIP_NO_ERROR == FindPair(endpoint, position), CHIP_NO_ERROR);

            uint16_t nextPos = static_cast<uint16_t>(position + 1);
            uint16_t moveNum = static_cast<uint16_t>(mPairCount - nextPos);

            // Compress array after removal, if the removed position is not the last
            if (moveNum)
            {
                memmove(&mStatePairBuffer[position], &mStatePairBuffer[nextPos], sizeof(EndpointStatePair<ValueType>) * moveNum);
            }

            mPairCount--;
            // Clear the last occupied position
            mStatePairBuffer[mPairCount].mEndpoint = kInvalidEndpointId;

            return CHIP_NO_ERROR;
        }

        uint16_t mPairCount = 0;
        EndpointStatePair<ValueType> mStatePairBuffer[MaxEndpointCount];
    };

    /// @brief Helper struct that allows clusters that do not have an existing mechanism for doing
    //         asynchronous work to perform scene transitions over some period of time.
    /// @tparam MaxEndpointCount
    template <size_t MaxEndpointCount, size_t FixedEndpointCount>
    struct TransitionTimeInterface
    {
        EmberEventControl sceneHandlerEventControls[MaxEndpointCount];

        TransitionTimeInterface(ClusterId clusterId, void (*callback)(EndpointId)) : mClusterId(clusterId), mCallback(callback) {}

        /**
         * @brief Configures EventControl callback
         *
         * @param[in] endpoint endpoint to start timer for
         * @return EmberEventControl* configured event control
         */
        EmberEventControl * sceneEventControl(EndpointId endpoint)
        {
            EmberEventControl * controller = getEventControl(endpoint, Span<EmberEventControl>(sceneHandlerEventControls));
            VerifyOrReturnValue(controller != nullptr, nullptr);

            controller->endpoint = endpoint;
            controller->callback = mCallback;

            return controller;
        }

        ClusterId mClusterId;
        void (*mCallback)(EndpointId);

    private:
        /**
         * @brief event control object for an endpoint
         *
         * @param[in] endpoint target endpoint
         * @param[in] eventControlArray Array where to find the event control
         * @return EmberEventControl* configured event control
         */
        EmberEventControl * getEventControl(EndpointId endpoint, const Span<EmberEventControl> & eventControlArray)
        {
            uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint, mClusterId, FixedEndpointCount);
            if (index >= eventControlArray.size())
            {
                return nullptr;
            }

            return &eventControlArray[index];
        }
    };

    static constexpr uint8_t kMaxAvPair = CHIP_CONFIG_SCENES_MAX_AV_PAIRS_EFS;

    DefaultSceneHandlerImpl() = default;
    ~DefaultSceneHandlerImpl() override{};

    /// @brief Encodes an attribute value list into a TLV structure and resizes the buffer to the size of the encoded data
    /// @param aVlist[in] Attribute value list to encode
    /// @param serializedBytes[out] Buffer to fill from the Attribute value list in a TLV format
    /// @return CHIP_ERROR
    virtual CHIP_ERROR EncodeAttributeValueList(const List<AttributeValuePairType> & aVlist, MutableByteSpan & serializedBytes);

    /// @brief Decodes an attribute value list from a TLV structure and ensure it fits the member pair buffer
    /// @param serializedBytes [in] Buffer to read from
    /// @param aVlist [out] Attribute value list to fill from the TLV structure.  Only valid while the buffer backing
    /// serializedBytes exists and its contents are not modified.
    /// @return CHIP_ERROR
    virtual CHIP_ERROR DecodeAttributeValueList(const ByteSpan & serializedBytes,
                                                DecodableList<AttributeValuePairDecodableType> & aVlist);

    /// @brief From command AddScene, allows handler to filter through clusters in command to serialize only the supported ones.
    /// @param endpoint[in] Endpoint ID
    /// @param extensionFieldSet[in] ExtensionFieldSets provided by the AddScene Command, pre initialized
    /// @param serializedBytes[out] Buffer to fill from the ExtensionFieldSet in command
    /// @return CHIP_NO_ERROR if successful, CHIP_ERROR_INVALID_ARGUMENT if the cluster is not supported, CHIP_ERROR value
    /// otherwise
    virtual CHIP_ERROR SerializeAdd(EndpointId endpoint, const ExtensionFieldSetDecodableType & extensionFieldSet,
                                    MutableByteSpan & serializedBytes) override;

    /// @brief Simulates taking data from nvm and loading it in a command object if the cluster is supported by the endpoint
    /// @param endpoint target endpoint
    /// @param cluster  target cluster
    /// @param serializedBytes data to deserialize into EFS
    /// @return CHIP_NO_ERROR if Extension Field Set was successfully populated, CHIP_ERROR_INVALID_ARGUMENT if the cluster is not
    /// supported, specific CHIP_ERROR otherwise
    virtual CHIP_ERROR Deserialize(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes,
                                   ExtensionFieldSetType & extensionFieldSet) override;

private:
    AttributeValuePairType mAVPairs[kMaxAvPair];
};

} // namespace scenes
} // namespace chip
