/*
 *
 *    Copyright (c) 2021 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.
 */

/**
 *    @file
 *      This file defines Reporting Engine for a CHIP Interaction Model
 *
 */

#pragma once

#include <access/AccessControl.h>
#include <app/MessageDef/ReportDataMessage.h>
#include <app/ReadHandler.h>
#include <app/util/basic-types.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <protocols/Protocols.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

namespace chip {
namespace app {
namespace reporting {
/*
 *  @class Engine
 *
 *  @brief The reporting engine is responsible for generating reports to reader. It is able to find the intersection
 * between the path interest set of each reader with what has changed in the publisher data store and generate tailored
 * reports for each reader.
 *
 *         At its core, it  tries to gather and pack as much relevant attributes changes and/or events as possible into a report
 * message before sending that to the reader. It continues to do so until it has no more work to do.
 */
class Engine
{
public:
    /**
     * Initializes the reporting engine. Should only be called once.
     *
     * @retval #CHIP_NO_ERROR On success.
     * @retval other           Was unable to retrieve data and write it into the writer.
     */
    CHIP_ERROR Init();

    void Shutdown();

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    void SetWriterReserved(uint32_t aReservedSize) { mReservedSize = aReservedSize; }

    void SetMaxAttributesPerChunk(uint32_t aMaxAttributesPerChunk) { mMaxAttributesPerChunk = aMaxAttributesPerChunk; }
#endif

    /**
     * Should be invoked when the device receives a Status report, or when the Report data request times out.
     * This allows the engine to do some clean-up.
     *
     */
    void OnReportConfirm();

    /**
     * Main work-horse function that executes the run-loop asynchronously on the CHIP thread
     */
    CHIP_ERROR ScheduleRun();

    /**
     * Application marks mutated change path and would be sent out in later report.
     */
    CHIP_ERROR SetDirty(AttributePathParams & aAttributePathParams);

    /**
     * @brief
     *  Schedule the event delivery
     *
     */
    CHIP_ERROR ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten);

    /*
     * Resets the tracker that tracks the currently serviced read handler.
     * apReadHandler can be non-null to indicate that the reset is due to a
     * specific ReadHandler being deallocated.
     */
    void ResetReadHandlerTracker(ReadHandler * apReadHandlerBeingDeleted)
    {
        if (apReadHandlerBeingDeleted == mRunningReadHandler)
        {
            // Just decrement, so our increment after we finish running it will
            // do the right thing.
            --mCurReadHandlerIdx;
        }
        else
        {
            // No idea what to do here to make the indexing sane.  Just start at
            // the beginning.  We need to do better here; see
            // https://github.com/project-chip/connectedhomeip/issues/13809
            mCurReadHandlerIdx = 0;
        }
    }

    uint32_t GetNumReportsInFlight() const { return mNumReportsInFlight; }

    uint64_t GetDirtySetGeneration() const { return mDirtyGeneration; }

    /**
     * Schedule event delivery to happen immediately and run reporting to get
     * those reports into messages and on the wire.  This can be done either for
     * a specific fabric, identified by the provided FabricIndex, or across all
     * fabrics if no FabricIndex is provided.
     */
    void ScheduleUrgentEventDeliverySync(Optional<FabricIndex> fabricIndex = NullOptional);

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    size_t GetGlobalDirtySetSize() { return mGlobalDirtySet.Allocated(); }
#endif

private:
    /**
     * Main work-horse function that executes the run-loop.
     */
    void Run();

    friend class TestReportingEngine;

    struct AttributePathParamsWithGeneration : public AttributePathParams
    {
        AttributePathParamsWithGeneration() {}
        AttributePathParamsWithGeneration(const AttributePathParams aPath) : AttributePathParams(aPath) {}
        uint64_t mGeneration = 0;
    };

    /**
     * Build Single Report Data including attribute changes and event data stream, and send out
     *
     */
    CHIP_ERROR BuildAndSendSingleReportData(ReadHandler * apReadHandler);

    CHIP_ERROR BuildSingleReportDataAttributeReportIBs(ReportDataMessage::Builder & reportDataBuilder, ReadHandler * apReadHandler,
                                                       bool * apHasMoreChunks, bool * apHasEncodedData);
    CHIP_ERROR BuildSingleReportDataEventReports(ReportDataMessage::Builder & reportDataBuilder, ReadHandler * apReadHandler,
                                                 bool aBufferIsUsed, bool * apHasMoreChunks, bool * apHasEncodedData);
    CHIP_ERROR RetrieveClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered,
                                   AttributeReportIBs::Builder & aAttributeReportIBs,
                                   const ConcreteReadAttributePath & aClusterInfo,
                                   AttributeValueEncoder::AttributeEncodeState * apEncoderState);
    CHIP_ERROR CheckAccessDeniedEventPaths(TLV::TLVWriter & aWriter, bool & aHasEncodedData, ReadHandler * apReadHandler);

    // If version match, it means don't send, if version mismatch, it means send.
    // If client sends the same path with multiple data versions, client will get the data back per the spec, because at least one
    // of those will fail to match.  This function should return false if either nothing in the list matches the given
    // endpoint+cluster in the path or there is an entry in the list that matches the endpoint+cluster in the path but does not
    // match the current data version of that cluster.
    bool IsClusterDataVersionMatch(const ObjectList<DataVersionFilter> * aDataVersionFilterList,
                                   const ConcreteReadAttributePath & aPath);

    /**
     * Send Report via ReadHandler
     *
     */
    CHIP_ERROR SendReport(ReadHandler * apReadHandler, System::PacketBufferHandle && aPayload, bool aHasMoreChunks);

    /**
     * Generate and send the report data request when there exists subscription or read request
     *
     */
    static void Run(System::Layer * aSystemLayer, void * apAppState);

    CHIP_ERROR ScheduleBufferPressureEventDelivery(uint32_t aBytesWritten);
    void GetMinEventLogPosition(uint32_t & aMinLogPosition);

    /**
     * If the provided path is a superset of our of our existing paths, update that existing path to match the
     * provided path.
     *
     * Return whether one of our paths is now a superset of the provided path.
     */
    bool MergeOverlappedAttributePath(const AttributePathParams & aAttributePath);

    /**
     * If we are running out of ObjectPool for the global dirty set, we will try to merge the existing items by clusters.
     *
     * Returns whether we have released any paths.
     */
    bool MergeDirtyPathsUnderSameCluster();

    /**
     * If we are running out of ObjectPool for the global dirty set and we cannot find a slot after merging the existing items by
     * clusters, we will try to merge the existing items by endpoints.
     *
     * Returns whether we have released any paths.
     */
    bool MergeDirtyPathsUnderSameEndpoint();

    /**
     * During the iterating of the paths, releasing the object in the inner loop will cause undefined behavior of the ObjectPool, so
     * we replace the items to be cleared by a tomb first, then clear all the tombs after the iteration.
     *
     * Returns whether we have released any paths.
     */
    bool ClearTombPaths();

    CHIP_ERROR InsertPathIntoDirtySet(const AttributePathParams & aAttributePath);

    inline void BumpDirtySetGeneration() { mDirtyGeneration++; }

    /**
     * Boolean to indicate if ScheduleRun is pending. This flag is used to prevent calling ScheduleRun multiple times
     * within the same execution context to avoid applying too much pressure on platforms that use small, fixed size event queues.
     *
     */
    bool mRunScheduled = false;

    /**
     * The number of report date request in flight
     *
     */
    uint32_t mNumReportsInFlight = 0;

    /**
     *  Current read handler index
     *
     */
    uint32_t mCurReadHandlerIdx = 0;

    /**
     * The read handler we're calling BuildAndSendSingleReportData on right now.
     */
    ReadHandler * mRunningReadHandler = nullptr;

    /**
     *  mGlobalDirtySet is used to track the set of attribute/event paths marked dirty for reporting purposes.
     *
     */
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    // For unit tests, always use inline allocation for code coverage.
    ObjectPool<AttributePathParamsWithGeneration, CHIP_IM_SERVER_MAX_NUM_DIRTY_SET, ObjectPoolMem::kInline> mGlobalDirtySet;
#else
    ObjectPool<AttributePathParamsWithGeneration, CHIP_IM_SERVER_MAX_NUM_DIRTY_SET> mGlobalDirtySet;
#endif

    /**
     * A generation counter for the dirty attrbute set.
     * ReadHandlers can save the generation value when generating reports.
     *
     * Then we can tell whether they might have missed reporting an attribute by
     * comparing its generation counter to the saved one.
     *
     * mDirtySetGeneration will increase by one when SetDirty is called.
     *
     * Count it from 1, so 0 can be used in ReadHandler to indicate "the read handler has never
     * completed a report".
     */
    uint64_t mDirtyGeneration = 1;

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    uint32_t mReservedSize          = 0;
    uint32_t mMaxAttributesPerChunk = UINT32_MAX;
#endif
};

}; // namespace reporting
}; // namespace app
}; // namespace chip
