/*
 *
 *    Copyright (c) 2022 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.
 */
#pragma once

#include <app-common/zap-generated/cluster-objects.h>
#include <app/clusters/scenes/ExtensionFieldSets.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/CommonIterator.h>
#include <lib/support/IntrusiveList.h>
#include <lib/support/PersistentData.h>
#include <lib/support/Span.h>

namespace chip {
namespace scenes {

// Storage index for scenes in nvm
typedef uint8_t SceneIndex;

typedef uint32_t TransitionTimeMs;
typedef uint32_t SceneTransitionTime;

constexpr GroupId kGlobalGroupSceneId        = 0x0000;
constexpr SceneIndex kUndefinedSceneIndex    = 0xff;
constexpr SceneId kUndefinedSceneId          = 0xff;
static constexpr uint8_t kMaxScenesPerFabric = CHIP_CONFIG_SCENES_MAX_PER_FABRIC;
static constexpr uint8_t kMaxScenesGlobal    = CHIP_CONFIG_SCENES_MAX_NUMBER;

static constexpr size_t kIteratorsMax       = CHIP_CONFIG_MAX_SCENES_CONCURRENT_ITERATORS;
static constexpr size_t kSceneNameMaxLength = CHIP_CONFIG_SCENES_CLUSTER_MAXIMUM_NAME_LENGTH;

/// @brief SceneHandlers are meant as interface between various clusters and the Scene table.
/// When a scene command involving extension field sets is received, the Scene Table will go through
/// the list of handlers to either retrieve, populate or apply those extension field sets.
///
/// Generally, for each specific <endpoint, cluster> pair there should be one and only one handler
/// registered with the scene table that claims to handle that pair.
///
/// A SceneHandler can handle a single <endpoint, cluster> pair, or many such pairs.
///
/// @note If more than one handler claims to handle a specific <endpoint, cluster> pair, only one of
/// those handlers will get called when executing actions related to extension field sets on the scene
/// table.  It is not defined which handler will be selected.

class SceneHandler : public IntrusiveListNodeBase<>
{
public:
    SceneHandler(){};
    virtual ~SceneHandler() = default;

    /// @brief Copies the list of supported clusters for an endpoint in a Span and resizes the span to fit the actual number of
    /// supported clusters
    /// @param endpoint target endpoint
    /// @param clusterBuffer Buffer to hold the supported cluster IDs, cannot hold more than
    /// CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE. The function shall use the reduce_size() method in the event it is supporting
    /// less than CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE clusters.
    virtual void GetSupportedClusters(EndpointId endpoint, Span<ClusterId> & clusterBuffer) = 0;

    /// @brief Returns whether or not a cluster for scenes is supported on an endpoint
    ///
    /// @param endpoint Target Endpoint ID
    /// @param cluster Target Cluster ID
    /// @return true if supported, false if not supported
    virtual bool SupportsCluster(EndpointId endpoint, ClusterId cluster) = 0;

    /// @brief Called when handling AddScene.  Allows the handler to filter through the clusters in the command to serialize only
    /// the supported ones.
    ///
    /// @param endpoint[in] Endpoint ID
    /// @param extensionFieldSet[in] ExtensionFieldSets provided by the AddScene Command, pre initialized
    /// @param serialisedBytes[out] Buffer to fill from the ExtensionFieldSet in command
    /// @return CHIP_NO_ERROR if successful, CHIP_ERROR value otherwise
    /// @note Only gets called after the scene-cluster has previously verified that the endpoint,cluster pair is supported by

    /// the handler. It is therefore the implementation's reponsibility to also implement the SupportsCluster method.
    virtual CHIP_ERROR SerializeAdd(EndpointId endpoint,
                                    const app::Clusters::Scenes::Structs::ExtensionFieldSet::DecodableType & extensionFieldSet,
                                    MutableByteSpan & serialisedBytes) = 0;

    /// @brief Called when handling StoreScene, and only if the handler supports the given endpoint and cluster.
    ///
    /// The implementation must write the actual scene data to store to serializedBytes as described below.
    ///
    /// @param endpoint[in] Target Endpoint
    /// @param cluster[in] Target Cluster
    /// @param serializedBytes[out] Output buffer, data needs to be writen in there and size adjusted to the size of the data
    /// written.
    ///
    /// @return CHIP_NO_ERROR if successful, CHIP_ERROR value otherwise
    virtual CHIP_ERROR SerializeSave(EndpointId endpoint, ClusterId cluster, MutableByteSpan & serializedBytes) = 0;

    /// @brief Deserialize an ExtensionFieldSet into a cluster object (e.g. when handling ViewScene).
    ///
    /// @param endpoint[in] Endpoint ID
    /// @param cluster[in] Cluster ID
    /// @param serializedBytes[in] ExtensionFieldSet stored in NVM
    ///
    /// @param extensionFieldSet[out] ExtensionFieldSet in command format
    /// @return CHIP_NO_ERROR if successful, CHIP_ERROR value otherwise
    /// @note Only gets called for handlers for which SupportsCluster() is true for the given endpoint and cluster.
    virtual CHIP_ERROR Deserialize(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes,

                                   app::Clusters::Scenes::Structs::ExtensionFieldSet::Type & extensionFieldSet) = 0;

    /// @brief Restore a stored scene for the given cluster instance, over timeMs milliseconds (e.g. when handling RecallScene)
    ///
    /// @param endpoint[in] Endpoint ID
    /// @param cluster[in] Cluster ID
    /// @param serializedBytes[in] ExtensionFieldSet stored in NVM
    ///
    /// @param timeMs[in] Transition time in ms to apply the scene
    /// @return CHIP_NO_ERROR if successful, CHIP_ERROR value otherwise
    /// @note Only gets called for handlers for which SupportsCluster() is true for the given endpoint and cluster.
    virtual CHIP_ERROR ApplyScene(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes,
                                  TransitionTimeMs timeMs) = 0;
};

template <class EFStype>
class SceneTable
{
public:
    /// @brief struct used to identify a scene in storage by 3 ids, endpoint, group and scene
    struct SceneStorageId
    {
        // Identifies endpoint to which this scene applies
        EndpointId mEndpointId = kInvalidEndpointId;
        // Identifies group within the scope of the given fabric
        GroupId mGroupId = kGlobalGroupSceneId;
        SceneId mSceneId = kUndefinedSceneId;

        SceneStorageId() = default;
        SceneStorageId(EndpointId endpoint, SceneId id, GroupId groupId = kGlobalGroupSceneId) :
            mEndpointId(endpoint), mGroupId(groupId), mSceneId(id)
        {}

        void Clear()
        {
            mEndpointId = kInvalidEndpointId;
            mGroupId    = kGlobalGroupSceneId;
            mSceneId    = kUndefinedSceneId;
        }

        bool IsValid() { return (mEndpointId != kInvalidEndpointId) && (mSceneId != kUndefinedSceneId); }

        bool operator==(const SceneStorageId & other)
        {
            return (mEndpointId == other.mEndpointId && mGroupId == other.mGroupId && mSceneId == other.mSceneId);
        }
    };

    /// @brief struct used to store data held in a scene
    /// Members:
    /// mName: char buffer holding the name of the scene, only serialized when mNameLenght is greater than 0
    /// mNameLength: lentgh of the name if a name was provided at scene creation
    /// mSceneTransitionTimeSeconds: Time in seconds it will take a cluster to change to the scene
    /// mExtensionFieldSets: class holding the different field sets of each cluster values to store with the scene
    /// mTransitionTime100ms: Transition time in tenths of a second, allows for more precise transition when combiened with
    /// mSceneTransitionTimeSeconds in enhanced scene commands
    struct SceneData
    {
        char mName[kSceneNameMaxLength]            = { 0 };
        size_t mNameLength                         = 0;
        SceneTransitionTime mSceneTransitionTimeMs = 0;
        EFStype mExtensionFieldSets;

        SceneData(const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) : mSceneTransitionTimeMs(time)
        {
            SetName(sceneName);
        }
        SceneData(EFStype fields, const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) :
            mSceneTransitionTimeMs(time)
        {
            SetName(sceneName);

            mExtensionFieldSets = fields;
        }
        SceneData(const SceneData & other) : mSceneTransitionTimeMs(other.mSceneTransitionTimeMs)
        {
            SetName(CharSpan(other.mName, other.mNameLength));

            mExtensionFieldSets = other.mExtensionFieldSets;
        }
        ~SceneData(){};

        void SetName(const CharSpan & sceneName)
        {
            if (nullptr == sceneName.data())
            {
                mName[0]    = 0;
                mNameLength = 0;
            }
            else
            {
                size_t maxChars = std::min(sceneName.size(), kSceneNameMaxLength);
                memcpy(mName, sceneName.data(), maxChars);
                mNameLength = maxChars;
            }
        }

        void Clear()
        {
            SetName(CharSpan());

            mSceneTransitionTimeMs = 0;
            mExtensionFieldSets.Clear();
        }

        bool operator==(const SceneData & other)
        {
            return (mNameLength == other.mNameLength && !memcmp(mName, other.mName, mNameLength) &&
                    (mSceneTransitionTimeMs == other.mSceneTransitionTimeMs) && (mExtensionFieldSets == other.mExtensionFieldSets));
        }

        void operator=(const SceneData & other)
        {
            SetName(CharSpan(other.mName, other.mNameLength));
            mExtensionFieldSets    = other.mExtensionFieldSets;
            mSceneTransitionTimeMs = other.mSceneTransitionTimeMs;
        }
    };

    /// @brief Struct combining both ID and data of a table entry
    struct SceneTableEntry
    {
        // ID
        SceneStorageId mStorageId;

        // DATA
        SceneData mStorageData;

        SceneTableEntry() = default;
        SceneTableEntry(SceneStorageId id) : mStorageId(id) {}
        SceneTableEntry(const SceneStorageId id, const SceneData data) : mStorageId(id), mStorageData(data) {}

        bool operator==(const SceneTableEntry & other)
        {
            return (mStorageId == other.mStorageId && mStorageData == other.mStorageData);
        }

        void operator=(const SceneTableEntry & other)
        {
            mStorageId   = other.mStorageId;
            mStorageData = other.mStorageData;
        }
    };

    SceneTable(){};

    virtual ~SceneTable() = default;

    // Not copyable
    SceneTable(const SceneTable &) = delete;

    SceneTable & operator=(const SceneTable &) = delete;

    virtual CHIP_ERROR Init(PersistentStorageDelegate * storage) = 0;
    virtual void Finish()                                        = 0;

    // Global scene count
    virtual CHIP_ERROR GetGlobalSceneCount(uint8_t & scene_count) = 0;

    // Data
    virtual CHIP_ERROR GetRemainingCapacity(FabricIndex fabric_index, uint8_t & capacity)                             = 0;
    virtual CHIP_ERROR SetSceneTableEntry(FabricIndex fabric_index, const SceneTableEntry & entry)                    = 0;
    virtual CHIP_ERROR GetSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id, SceneTableEntry & entry) = 0;
    virtual CHIP_ERROR RemoveSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id)                       = 0;
    virtual CHIP_ERROR RemoveSceneTableEntryAtPosition(FabricIndex fabric_index, SceneIndex scene_idx)                = 0;

    // Groups
    virtual CHIP_ERROR GetAllSceneIdsInGroup(FabricIndex fabric_index, GroupId group_id, Span<SceneId> & scene_list) = 0;
    virtual CHIP_ERROR DeleteAllScenesInGroup(FabricIndex fabric_index, GroupId group_id)                            = 0;

    // SceneHandlers
    virtual void RegisterHandler(SceneHandler * handler)   = 0;
    virtual void UnregisterHandler(SceneHandler * handler) = 0;
    virtual void UnregisterAllHandlers()                   = 0;

    // Extension field sets operation
    virtual CHIP_ERROR SceneSaveEFS(SceneTableEntry & scene)        = 0;
    virtual CHIP_ERROR SceneApplyEFS(const SceneTableEntry & scene) = 0;

    // Fabrics
    virtual CHIP_ERROR RemoveFabric(FabricIndex fabric_index) = 0;

    // Iterators
    using SceneEntryIterator = CommonIterator<SceneTableEntry>;

    virtual SceneEntryIterator * IterateSceneEntries(FabricIndex fabric_index) = 0;

    // Handlers
    virtual bool HandlerListEmpty() { return mHandlerList.Empty(); }

    IntrusiveList<SceneHandler> mHandlerList;
};

} // namespace scenes
} // namespace chip
