/*
 *
 *    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 {

class TestReadInteraction;

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;
    friend class ::chip::app::TestReadInteraction;

    bool IsRunScheduled() const { return mRunScheduled; }

    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
