/*
 *    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/TLVReader.h>
#include <lib/core/TLVWriter.h>

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

#include <app/interaction-model/Actions.h>
#include <app/interaction-model/InvokeResponder.h>
#include <app/interaction-model/IterationTypes.h>
#include <app/interaction-model/OperationTypes.h>

namespace chip {
namespace app {
namespace InteractionModel {

/// 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 Model : public AttributeTreeIterator
{
public:
    virtual ~Model() = default;

    // `actions` pointers  will be guaranteed valid until Shutdown is called()
    virtual CHIP_ERROR Startup(InteractionModelActions actions)
    {
        mActions = actions;
        return CHIP_NO_ERROR;
    }
    virtual CHIP_ERROR Shutdown() = 0;

    // During the transition phase, we expect a large subset of code to require access to
    // event emitting, path marking and other operations
    virtual InteractionModelActions CurrentActions() { return mActions; }

    /// List reading has specific handling logic:
    ///   `state` contains in/out data about the current list reading. MUST start with kInvalidListIndex on first call
    ///
    /// Return codes:
    ///   CHIP_ERROR_MORE_LIST_DATA_AVAILABLE (NOTE: new error defined for this purpose)
    ///      - partial data written to the destination
    ///      - destination will contain AT LEAST one valid list entry fully serialized
    ///      - destination will be fully valid (it will be rolled back on partial list writes)
    ///   CHIP_IM_GLOBAL_STATUS(code):
    ///      - error codes that are translatable in IM status codes (otherwise we expect Failure to be reported)
    ///      - In particular, some handlers rely on special handling for:
    ///        - `UnsupportedAccess`  - for ACL checks (e.g. wildcard expansion may choose to skip these)
    ///      - to check for this, CHIP_ERROR provides:
    ///        - ::IsPart(ChipError::SdkPart::kIMGlobalStatus) -> bool
    ///        - ::GetSdkCode() -> uint8_t to translate to the actual code
    virtual CHIP_ERROR ReadAttribute(const ReadAttributeRequest & request, ReadState & state, 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
    ///
    /// List operation support:
    ///    - the first list write will have `request.writeFlags.Has(WriteFlags::kListBegin)`
    ///    - the last list write will have `request.writeFlags.Has(WriteFlags::kListEnd)`
    ///    - the last list write MAY have empty data (no list items)
    ///
    /// When `request.writeFlags.Has(WriteFlags::kForceInternal)` the request is from an internal app update
    /// and SHOULD bypass some internal checks (like timed enforcement, potentially read-only restrictions)
    ///
    /// Return codes
    ///   CHIP_IM_GLOBAL_STATUS(code):
    ///       - error codes that are translatable to specific IM codes
    ///       - in particular, the following codes are interesting/expected
    ///         - `UnsupportedWrite` for attempts to write read-only data
    ///         - `UnsupportedAccess` for ACL failures
    ///         - `NeedsTimedInteraction` for writes that are not timed however are required to be so
    virtual CHIP_ERROR WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0;

    /// `responder` is used to send back the reply.
    ///    - calling Reply() or ReplyAsync() will let the application control the reply
    ///    - returning a CHIP_NO_ERROR without reply/reply_async implies a Status::Success reply without data
    ///    - returning a CHIP_*_ERROR implies an error reply (error and data are mutually exclusive)
    ///
    /// See InvokeReply/AutoCompleteInvokeResponder for details on how to send back replies and expected
    /// error handling. If you require knowledge if a response was successfully sent, use the underlying
    /// `reply` object instead of returning an error codes from Invoke.
    ///
    /// Return codes
    ///   CHIP_IM_GLOBAL_STATUS(code):
    ///       - error codes that are translatable to specific IM codes
    ///       - in particular, the following codes are interesting/expected
    ///         - `UnsupportedEndpoint` for invalid endpoint
    ///         - `UnsupportedCluster` for no such cluster on the endpoint
    ///         - `UnsupportedCommand` for no such command in the cluster
    ///         - `UnsupportedAccess` for permission errors (ACL or fabric scoped with invalid fabric)
    ///         - `NeedsTimedInteraction` if the invoke requires timed interaction support
    virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, InvokeReply & reply) = 0;

private:
    InteractionModelActions mActions = { nullptr };
};

} // namespace InteractionModel
} // namespace app
} // namespace chip
