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

#include <app/ConcreteClusterPath.h>
#include <app/server-cluster/ServerClusterInterface.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>

#include <cstdint>
#include <new>
#include <optional>

namespace chip {
namespace app {

/// Represents an entry in the server cluster interface registry for
/// a specific interface.
///
/// In practice this is a single-linked list element.
struct ServerClusterRegistration
{
    // A single-linked list of clusters registered for the given `endpointId`
    ServerClusterInterface * const serverClusterInterface;
    ServerClusterRegistration * next;

    constexpr ServerClusterRegistration(ServerClusterInterface & interface, ServerClusterRegistration * next_item = nullptr) :
        serverClusterInterface(&interface), next(next_item)
    {}
    ServerClusterRegistration(ServerClusterRegistration && other) = default;

    // we generally do not want to allow copies as those may have different "next" entries.
    ServerClusterRegistration(const ServerClusterRegistration & other)             = delete;
    ServerClusterRegistration & operator=(const ServerClusterRegistration & other) = delete;
};

/// It is very typical to join together a registration and a Server
/// This templates makes this registration somewhat easier/standardized.
template <typename SERVER_CLUSTER>
struct RegisteredServerCluster
{
    template <typename... Args>
    RegisteredServerCluster(Args &&... args) : cluster(std::forward<Args>(args)...), registration(cluster)
    {}

    [[nodiscard]] constexpr ServerClusterRegistration & Registration() { return registration; }
    [[nodiscard]] constexpr SERVER_CLUSTER & Cluster() { return cluster; }

private:
    SERVER_CLUSTER cluster;
    ServerClusterRegistration registration;
};

/// Lazy-construction of a RegisteredServerCluster to allow at-runtime lifetime management
///
/// If using this class, manamement of Create/Destroy MUST be done correctly.
template <typename SERVER_CLUSTER>
struct LazyRegisteredServerCluster
{
public:
    constexpr LazyRegisteredServerCluster() = default;
    ~LazyRegisteredServerCluster()
    {
        if (IsConstructed())
        {
            Destroy();
        }
    }

    void Destroy()
    {
        VerifyOrDie(IsConstructed());
        Registration().~ServerClusterRegistration();
        memset(mRegistration, 0, sizeof(mRegistration));

        Cluster().~SERVER_CLUSTER();
        memset(mCluster, 0, sizeof(mCluster));
    }

    template <typename... Args>
    void Create(Args &&... args)
    {
        VerifyOrDie(!IsConstructed());

        new (mCluster) SERVER_CLUSTER(std::forward<Args>(args)...);
        new (mRegistration) ServerClusterRegistration(Cluster());
    }

    [[nodiscard]] constexpr bool IsConstructed() const
    {
        // mRegistration is supposed to containt a serverClusterInterface that is NOT null
        // so we check for non-zero content. This relies that nullptr is 0
        return Registration().serverClusterInterface != nullptr;
    }

    [[nodiscard]] constexpr ServerClusterRegistration & Registration()
    {
        return *std::launder(reinterpret_cast<ServerClusterRegistration *>(mRegistration));
    }

    [[nodiscard]] constexpr const ServerClusterRegistration & Registration() const
    {
        return *std::launder(reinterpret_cast<const ServerClusterRegistration *>(mRegistration));
    }

    [[nodiscard]] constexpr SERVER_CLUSTER & Cluster() { return *std::launder(reinterpret_cast<SERVER_CLUSTER *>(mCluster)); }

    [[nodiscard]] constexpr const SERVER_CLUSTER & Cluster() const
    {
        return *std::launder(reinterpret_cast<const SERVER_CLUSTER *>(mCluster));
    }

private:
    alignas(SERVER_CLUSTER) uint8_t mCluster[sizeof(SERVER_CLUSTER)]                            = { 0 };
    alignas(ServerClusterRegistration) uint8_t mRegistration[sizeof(ServerClusterRegistration)] = { 0 };
};

/// Allows registering and retrieving ServerClusterInterface instances for specific cluster paths.
class ServerClusterInterfaceRegistry
{
public:
    ~ServerClusterInterfaceRegistry();

    /// Add the given entry to the registry.
    ///
    /// Requirements:
    ///   - entry MUST NOT be part of any other registration
    ///   - LIFETIME of entry must outlive the Registry (or entry must be unregistered)
    ///
    /// There can be only a single registration for a given `endpointId/clusterId` path.
    [[nodiscard]] CHIP_ERROR Register(ServerClusterRegistration & entry);

    /// Remove an existing registration
    ///
    /// Will return CHIP_ERROR_NOT_FOUND if the given registration is not found.
    CHIP_ERROR Unregister(ServerClusterInterface *);

    /// Return the interface registered for the given cluster path or nullptr if one does not exist
    ServerClusterInterface * Get(const ConcreteClusterPath & path);

    // Set up the underlying context for all clusters that are managed by this registry.
    //
    // The values within context will be moved and used as-is.
    CHIP_ERROR SetContext(ServerClusterContext && context);

    // Invalidates current context.
    void ClearContext();

    // Represents an iterable list of all clusters registered in this registry.
    // The list is only valid as long as the registry is not modified.
    // The list is not guaranteed to be in any particular order.
    class ServerClusterInstances
    {
    public:
        class Iterator
        {
        public:
            Iterator(ServerClusterRegistration * registration) : mRegistration(registration) {}

            Iterator & operator++()
            {
                if (mRegistration)
                {
                    mRegistration = mRegistration->next;
                }
                return *this;
            }
            bool operator==(const Iterator & other) const { return mRegistration == other.mRegistration; }
            bool operator!=(const Iterator & other) const { return mRegistration != other.mRegistration; }
            ServerClusterInterface * operator*() { return mRegistration ? mRegistration->serverClusterInterface : nullptr; }

        private:
            ServerClusterRegistration * mRegistration;
        };

        constexpr ServerClusterInstances(ServerClusterRegistration * start) : mStart(start) {}
        Iterator begin() { return { mStart }; }
        Iterator end() { return { nullptr }; }

    private:
        ServerClusterRegistration * mStart;
    };

    ServerClusterInstances AllServerClusterInstances();

protected:
    ServerClusterRegistration * mRegistrations = nullptr;

    // A one-element cache to speed up finding a cluster within an endpoint.
    // The endpointId specifies which endpoint the cache belongs to.
    ServerClusterInterface * mCachedInterface = nullptr;

    // Managing context for this registry
    std::optional<ServerClusterContext> mContext;
};

} // namespace app
} // namespace chip
