/*
 *    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/CommandHandlerInterface.h>
#include <app/ConcreteCommandPath.h>
#include <app/data-model-provider/ActionReturnStatus.h>
#include <app/data-model-provider/MetadataTypes.h>
#include <app/data-model-provider/Provider.h>
#include <app/persistence/AttributePersistenceProvider.h>
#include <app/server-cluster/ServerClusterInterface.h>
#include <app/server-cluster/ServerClusterInterfaceRegistry.h>
#include <data-model-providers/codedriven/endpoint/EndpointInterface.h>
#include <data-model-providers/codedriven/endpoint/EndpointInterfaceRegistry.h>
#include <lib/support/ReadOnlyBuffer.h>

namespace chip {
namespace app {
/**
 * @brief An implementation of DataModel::Provider that constructs the data model
 *        programmatically by aggregating EndpointInterface instances.
 *
 * This provider allows applications to define their Matter device data model (endpoints,
 * clusters, attributes, commands) dynamically at runtime. It manages a list of EndpointInterface
 * objects, each representing an endpoint on the device.
 *
 * The expected usage pattern by the application is as follows:
 * 1. Instantiate ServerClusterInterface(s) and ServerClusterRegistration(s).
 * 2. Instantiate EndpointInterface(s) and EndpointInterfaceRegistration(s).
 * 2. Instantiate the CodeDrivenDataModelProvider.
 * 3. Register ServerClusterInterfaceRegistration(s) to the CodeDrivenDataModelProvider using AddCluster().
 * 4. Register EndpointInterfaceRegistration(s) to the CodeDrivenDataModelProvider using AddEndpoint().
 *    Note: Step 4 MUST come after Step 3 (Endpoint needs to know about its clusters).
 * 5. Call Startup() on the CodeDrivenDataModelProvider.
 *
 * Note: if the CodeDrivenDataModelProvider has already been started (runtime change to add/remove Endpoints/Clusters),
 *       the Startup() method on each ServerClusterInterface will be called when the EndpointInterface is added (Step 4).
 *       If the provider hasn't been started, the Startup() method will be called when the provider is started (Step 5).
 *
 * TODO: Notify composition changes when the provider is started up and endpoints are added/removed at runtime.
 *       For now, applications are responsible for handling composition changes and calling markDirty() when needed.
 *
 * Lifecycle:
 * - The CodeDrivenDataModelProvider stores raw pointers to EndpointInterface and ServerClusterInterface.
 *   It does NOT take ownership. Callers must ensure these instances outlive the provider.
 */
class CodeDrivenDataModelProvider : public DataModel::Provider
{
public:
    CodeDrivenDataModelProvider(PersistentStorageDelegate & storage, AttributePersistenceProvider & attributeStorage) :
        mPersistentStorageDelegate(storage), mAttributePersistenceProvider(attributeStorage)
    {}

    /* DataModel::Provider implementation */
    CHIP_ERROR Startup(DataModel::InteractionModelContext context) override;
    CHIP_ERROR Shutdown() override;

    DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request,
                                                AttributeValueEncoder & encoder) override;
    DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request,
                                                 AttributeValueDecoder & decoder) override;

    void ListAttributeWriteNotification(const ConcreteAttributePath & path, DataModel::ListWriteOperation opType) override;
    std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
                                                               TLV::TLVReader & input_arguments, CommandHandler * handler) override;

    /* ProviderMetadataTree implementation */
    CHIP_ERROR Endpoints(ReadOnlyBufferBuilder<DataModel::EndpointEntry> & out) override;
    CHIP_ERROR SemanticTags(EndpointId endpointId,
                            ReadOnlyBufferBuilder<Clusters::Descriptor::Structs::SemanticTagStruct::Type> & out) override;
    CHIP_ERROR DeviceTypes(EndpointId endpointId, ReadOnlyBufferBuilder<DataModel::DeviceTypeEntry> & out) override;
    CHIP_ERROR ClientClusters(EndpointId endpointId, ReadOnlyBufferBuilder<ClusterId> & out) override;
    CHIP_ERROR ServerClusters(EndpointId endpointId, ReadOnlyBufferBuilder<DataModel::ServerClusterEntry> & out) override;
    CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<CommandId> & out) override;
    CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path,
                                ReadOnlyBufferBuilder<DataModel::AcceptedCommandEntry> & out) override;
    CHIP_ERROR Attributes(const ConcreteClusterPath & path, ReadOnlyBufferBuilder<DataModel::AttributeEntry> & builder) override;
    CHIP_ERROR EventInfo(const ConcreteEventPath & path, DataModel::EventEntry & eventInfo) override;
    void Temporary_ReportAttributeChanged(const AttributePathParams & path) override;

    /**
     * @brief Adds an endpoint to the data model provider.
     *
     * This method registers an endpoint, making it part of the device's data model.
     * If the provider has already been started, this may trigger a Startup() call on
     * each ServerClusterInterface associated with the endpoint.
     * The Startup() call on the associated clusters will ONLY happen if this is the first
     * endpoint associated with the cluster (i.e. ServerClusterInterface.GetPaths() returns
     * at least one path with endpoint ID == registration.endpointEntry.id, and none
     * of the other endpoints in GetPaths() are registered yet). This ensures
     * the cluster is only started once, even if it is associated with multiple endpoints.
     *
     * Prerequisites:
     *   - It MUST be called after all clusters for the endpoint have been registered with
     *     AddCluster().
     *   - The provided `registration` (EndpointInterfaceRegistration) must not already be
     *     part of another list (i.e., `registration.next` must be nullptr).
     *   - The EndpointInterface within the `registration` must be valid (i.e.,
     *     `registration.endpointInterface` must not be nullptr).
     *   - The `registration.endpointEntry.id` must be valid (not `kInvalidEndpointId` and
     *     not used by another endpoint).
     *   - The LIFETIME of `registration` must outlive the provider (or the registration must
     *     be removed using `RemoveEndpoint` before it goes away).
     *
     * @param registration The registration object for the endpoint, containing a valid
     *                     EndpointInterface and Endpoint ID.
     * @return CHIP_NO_ERROR on success.
     *         CHIP_ERROR_INVALID_ARGUMENT if `registration.next` is not nullptr or
     *                                     `registration.endpointInterface` is nullptr or
     *                                     `registration.endpointEntry.id` is kInvalidEndpointId.
     *         CHIP_ERROR_DUPLICATE_KEY_ID if `registration.endpointEntry.id` is already in use.
     */
    CHIP_ERROR AddEndpoint(EndpointInterfaceRegistration & registration);

    /**
     * @brief Removes an endpoint from the data model provider.
     *
     * This method unregisters an endpoint, removing it from the device's data model.
     * If the provider has already been started, this might trigger a Shutdown() call on
     * each ServerClusterInterface associated with the endpoint.
     * The Shutdown() call on the associated clusters will ONLY happen if this is the last
     * endpoint associated with the cluster (i.e. ServerClusterInterface.GetPaths() returns
     * no paths with valid Endpoint IDs).
     *
     * Note: Removing an Endpoint does not remove any clusters associated with the endpoint.
     *       Those can be removed using RemoveCluster() AFTER the endpoint has been removed.

     * Prerequisites:
     *   - It MUST be called BEFORE removing associted clusters with RemoveCluster() to guarantee
     *     the endpoint removal is atomic.
     *   - The endpoint ID must be valid.
     *
     * @param endpointId The ID of the endpoint to remove.
     * @return CHIP_NO_ERROR on success.
     *         CHIP_ERROR_NOT_FOUND if no endpoint with the given ID is registered.
     *         CHIP_ERROR_INVALID_ARGUMENT if endpointId is kInvalidEndpointId.
     */
    CHIP_ERROR RemoveEndpoint(EndpointId endpointId);

    /**
     * @brief Add a ServerClusterInterface to the Data Model Provider.
     *
     * Requirements:
     *   - entry MUST NOT be part of any other registration
     *   - paths MUST NOT be part of any other ServerClusterInterface (i.e. only a single
     *     registration for a given `endpointId/clusterId` path).
     *   - The LIFETIME of entry must outlive the provider (or the entry must be unregistered
     *     via RemoveCluster before it goes away).
     *   - If the provider has already been started, this method must be called prior to
     *     calling AddEndpoint() (i.e. the `endpointId` of all paths in `entry.GetPaths()`
     *     must NOT be registered in the provider yet), otherwise this would cause non-atomic
     *     changes to an endpoint, which is not allowed.
     *
     * @param entry The ServerClusterRegistration containing the cluster to register.
     * @return CHIP_NO_ERROR on success.
     *         CHIP_ERROR_INVALID_ARGUMENT if `entry.next` is not `nullptr` or
     *                                     `entry.serverClusterInterface` is `nullptr` or
     *                                     `entry.serverClusterInterface.GetPaths()` is empty/invalid.
     *         CHIP_ERROR_DUPLICATE_KEY_ID if the cluster is already registered.
     *         CHIP_ERROR_INCORRECT_STATE if the provider has been started and an endpoint for
     *                                    one of the cluster paths has already been registered.
     */
    CHIP_ERROR AddCluster(ServerClusterRegistration & entry);

    /**
     * @brief Remove a ServerClusterInterface from the Data Model Provider.
     *
     * To avoid violating the requirement of non-atomic changes to endpoints, this SHALL only be
     * called after all endpoints associated with the cluster have been removed using RemoveEndpoint().
     *
     * Requirements:
     *   - entry MUST be valid
     *   - The `endpointId` of all paths in `entry.GetPaths()` are no longer registered in the provider.
     *
     * @param entry The ServerClusterInterface to remove.
     * @return CHIP_NO_ERROR on success.
     *         CHIP_ERROR_INVALID_ARGUMENT if `entry` is nullptr.
     *         CHIP_ERROR_NOT_FOUND if the entry is not registered.
     *         CHIP_ERROR_INCORRECT_STATE if an endpoint for one of the cluster paths is still registered.
     */
    CHIP_ERROR RemoveCluster(ServerClusterInterface * entry);

private:
    EndpointInterfaceRegistry mEndpointInterfaceRegistry;
    ServerClusterInterfaceRegistry mServerClusterRegistry;
    std::optional<ServerClusterContext> mServerClusterContext;
    std::optional<DataModel::InteractionModelContext> mInteractionModelContext;
    PersistentStorageDelegate & mPersistentStorageDelegate;
    AttributePersistenceProvider & mAttributePersistenceProvider;

    /// Return the interface registered for the given endpoint ID or nullptr if one does not exist
    EndpointInterface * GetEndpointInterface(EndpointId endpointId);

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

} // namespace app
} // namespace chip
