/*
 *    Copyright (c) 2024 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 <lib/core/CHIPError.h>
#include <lib/core/TLVReader.h>
#include <lib/core/TLVWriter.h>

#include <app/AttributeValueDecoder.h>
#include <app/AttributeValueEncoder.h>
#include <app/CommandHandler.h>

#include <app/data-model-provider/ActionReturnStatus.h>
#include <app/data-model-provider/Context.h>
#include <app/data-model-provider/OperationTypes.h>
#include <app/data-model-provider/ProviderMetadataTree.h>

namespace chip {
namespace app {
namespace DataModel {

/// Represents operations against a matter-defined data model.
///
/// Class is SINGLE-THREADED:
///   - operations are assumed to only be ever run in a single event-loop
///     thread or equivalent
///   - class is allowed to attempt to cache indexes/locations for faster
///     lookups of things (e.g during iterations)
class Provider : public ProviderMetadataTree
{
public:
    ~Provider() override = default;

    // `context` references  will be guaranteed valid until Shutdown is called()
    virtual CHIP_ERROR Startup(InteractionModelContext context) { return CHIP_NO_ERROR; }
    virtual CHIP_ERROR Shutdown() { return CHIP_NO_ERROR; }

    /// NOTE: this code is NOT required to handle `List` global attributes:
    ///       AcceptedCommandsList, GeneratedCommandsList OR AttributeList
    ///
    ///       Users of DataModel::Provider are expected to get these lists
    ///       from ProviderMetadataTree (in particular IM Reads of these
    ///       attributes will be automatically filled from metadata).
    ///
    /// When this is invoked, caller is expected to have already done some validations:
    ///    - `request.path` is a valid path inside the ProviderMetadataTree (an AttributeEntry exists)
    ///    - Attribute is readable according to the ProviderMetadataTree/AttributeEntry data
    ///    - Appropriate ACL checks done according to the attribute's AttributeEntry
    ///
    /// Return value notes:
    ///   ActionReturnStatus::IsOutOfSpaceEncodingResponse
    ///      - Indicates that list encoding had insufficient buffer space to encode elements.
    ///      - encoder::GetState().AllowPartialData() determines if these errors are permanent (no partial
    ///        data allowed) or further encoding can be retried (AllowPartialData true for list encoding)
    virtual ActionReturnStatus ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) = 0;

    /// Requests a write of an attribute.
    ///
    /// When this is invoked, caller is expected to have already done some validations:
    ///    - cluster `data version` has been checked for the incoming request if applicable
    ///    - validation of ACL/timed interaction flags/writability, if those checks are desired.
    ///    - `request.path` is a valid path inside the ProviderMetadataTree (an AttributeEntry exists)
    ///    - Attribute is writable according to the ProviderMetadataTree/AttributeEntry data
    ///    - Appropriate ACL checks done according to the attribute's AttributeEntry
    virtual ActionReturnStatus WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0;

    ///   Indicates the start/end of a series of list operations. This function will be called either before the first
    ///   Write operation or after the last one of a series of consecutive attribute data of the same attribute.
    ///
    ///   1) This function will be called if the client tries to set a nullable list attribute to null.
    ///   2) This function will only be called at the beginning and end of a series of consecutive attribute data
    ///   blocks for the same attribute, no matter what list operations those data blocks represent.
    ///   3) The opType argument indicates the type of notification (Start, Failure, Success).
    virtual void ListAttributeWriteNotification(const ConcreteAttributePath & aPath, ListWriteOperation opType) = 0;

    /// `handler` is used to send back the reply.
    ///    - returning `std::nullopt` means that return value was placed in handler directly.
    ///      This includes cases where command handling and value return will be done asynchronously.
    ///    - returning a value other than Success implies an error reply (error and data are mutually exclusive)
    ///
    /// Preconditions:
    ///    - `request.path` MUST refer to a command that actually exists.  This is because in practice
    ///       callers must do ACL and flag checks (e.g. for timed invoke) before calling this function.
    ///
    ///       Callers that do not care about those checks should use `ProviderMetadataTree::AcceptedCommands`
    ///       to check for command existence.
    ///
    ///    - TODO: as interfaces are updated, we may want to make the above requirement more
    ///            relaxed, as it seems desirable for users of this interface to have guaranteed
    ///            behavior (like error on invalid paths) whereas today this seems unclear as some
    ///            command intercepts do not validate that the command is in fact accepted on the
    ///            endpoint provided.
    ///
    /// Return value expectations:
    ///   - if a response has been placed into `handler` then std::nullopt MUST be returned. In particular
    ///     note that CHIP_NO_ERROR is NOT the same as std::nullopt:
    ///        > CHIP_NO_ERROR means handler had no status set and we expect the caller to AddStatus(success)
    ///        > std::nullopt means that handler has added an appropriate data/status response
    ///   - if a value is returned (not nullopt) then the handler response MUST NOT be filled. The caller
    ///     will then issue `handler->AddStatus(request.path, <return_value>->GetStatusCode())`. This is a
    ///     convenience to make writing Invoke calls easier.
    virtual std::optional<ActionReturnStatus> InvokeCommand(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments,
                                                            CommandHandler * handler) = 0;
};

} // namespace DataModel
} // namespace app
} // namespace chip
