/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    Copyright (c) 2015-2017 Nest Labs, Inc.
 *    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
 *
 * @brief
 *   Management of the CHIP Event Logging.
 *
 */
#pragma once

#include "EventLoggingDelegate.h"
#include "EventLoggingTypes.h"
#include <access/SubjectDescriptor.h>
#include <app/MessageDef/EventDataIB.h>
#include <app/MessageDef/StatusIB.h>
#include <app/ObjectList.h>
#include <app/util/basic-types.h>
#include <lib/core/CHIPCircularTLVBuffer.h>
#include <lib/support/CHIPCounter.h>
#include <messaging/ExchangeMgr.h>

#define CHIP_CONFIG_EVENT_GLOBAL_PRIORITY PriorityLevel::Debug

namespace chip {
namespace app {
constexpr const uint32_t kEventManagementProfile = 0x1;
constexpr const uint32_t kFabricIndexTag         = 0x1;
constexpr size_t kMaxEventSizeReserve            = 512;
constexpr uint16_t kRequiredEventField =
    (1 << to_underlying(EventDataIB::Tag::kPriority)) | (1 << to_underlying(EventDataIB::Tag::kPath));

/**
 * @brief
 *   Internal event buffer, built around the TLV::CHIPCircularTLVBuffer
 */

class CircularEventBuffer : public TLV::CHIPCircularTLVBuffer
{
public:
    /**
     * @brief
     *   A constructor for the CircularEventBuffer (internal API).
     */
    CircularEventBuffer() : CHIPCircularTLVBuffer(nullptr, 0){};

    /**
     * @brief
     *   A Init for the CircularEventBuffer (internal API).
     *
     * @param[in] apBuffer       The actual storage to use for event storage.
     *
     * @param[in] aBufferLength The length of the \c apBuffer in bytes.
     *
     * @param[in] apPrev         The pointer to CircularEventBuffer storing
     *                           events of lesser priority.
     *
     * @param[in] apNext         The pointer to CircularEventBuffer storing
     *                           events of greater priority.
     *
     * @param[in] aPriorityLevel CircularEventBuffer priority level
     */
    void Init(uint8_t * apBuffer, uint32_t aBufferLength, CircularEventBuffer * apPrev, CircularEventBuffer * apNext,
              PriorityLevel aPriorityLevel);

    /**
     * @brief
     *   A helper function that determines whether the event of
     *   specified priority is final destination
     *
     * @param[in]   aPriority   Priority of the event.
     *
     * @retval true/false event's priority is same as current buffer's priority, otherwise, false
     */
    bool IsFinalDestinationForPriority(PriorityLevel aPriority) const;

    PriorityLevel GetPriority() { return mPriority; }

    CircularEventBuffer * GetPreviousCircularEventBuffer() { return mpPrev; }
    CircularEventBuffer * GetNextCircularEventBuffer() { return mpNext; }

    void SetRequiredSpaceforEvicted(size_t aRequiredSpace) { mRequiredSpaceForEvicted = aRequiredSpace; }
    size_t GetRequiredSpaceforEvicted() const { return mRequiredSpaceForEvicted; }

    ~CircularEventBuffer() override = default;

private:
    CircularEventBuffer * mpPrev = nullptr; ///< A pointer CircularEventBuffer storing events less important events
    CircularEventBuffer * mpNext = nullptr; ///< A pointer CircularEventBuffer storing events more important events

    PriorityLevel mPriority = PriorityLevel::Invalid; ///< The buffer is the final bucket for events of this priority.  Events of
                                                      ///< lesser priority are dropped when they get bumped out of this buffer

    size_t mRequiredSpaceForEvicted = 0; ///< Required space for previous buffer to evict event to new buffer
};

class CircularEventReader;

/**
 * @brief
 *   A CircularEventBufferWrapper which has a pointer to the "current CircularEventBuffer". When trying to locate next buffer,
 *   if nothing left there update its CircularEventBuffer until the buffer with data has been found,
 *   the tlv reader will have a pointer to this impl.
 */
class CircularEventBufferWrapper : public TLV::CHIPCircularTLVBuffer
{
public:
    CircularEventBufferWrapper() : CHIPCircularTLVBuffer(nullptr, 0), mpCurrent(nullptr){};
    CircularEventBuffer * mpCurrent;

private:
    CHIP_ERROR GetNextBuffer(chip::TLV::TLVReader & aReader, const uint8_t *& aBufStart, uint32_t & aBufLen) override;
};

enum class EventManagementStates
{
    Idle       = 1, // No log offload in progress, log offload can begin without any constraints
    InProgress = 2, // Log offload in progress
    Shutdown   = 3  // Not capable of performing any logging operation
};

/**
 * @brief
 *   A helper class used in initializing logging management.
 *
 * The class is used to encapsulate the resources allocated by the caller and denotes
 * resources to be used in logging events of a particular priority.  Note that
 * while resources referring to the counters are used exclusively by the
 * particular priority level, the buffers are shared between `this` priority
 * level and events that are "more" important.
 */

struct LogStorageResources
{
    // TODO: Update CHIPCircularTLVBuffer with size_t for buffer size, then use ByteSpan
    uint8_t * mpBuffer =
        nullptr; // Buffer to be used as a storage at the particular priority level and shared with more important events.
                 // Must not be nullptr.  Must be large enough to accommodate the largest event emitted by the system.
    uint32_t mBufferSize = 0; ///< The size, in bytes, of the `mBuffer`.
    PriorityLevel mPriority =
        PriorityLevel::Invalid; // Log priority level associated with the resources provided in this structure.
};

/**
 * @brief
 *   A class for managing the in memory event logs.
 *   Assume we have two importance levels. DEBUG and CRITICAL, for simplicity,
 *   A new incoming event will always get logged in buffer with debug buffer no matter it is Debug or CRITICAL event.
 *   In order for it to get logged, we need to free up space.  So we look at the tail of the buffer.
 *   If the tail of the buffer contains a DEBUG event, that will be dropped.  If the tail of the buffer contains
 *   a CRITICAL event, that  event will be 'promoted' to the next level of buffers, where it will undergo the same procedure
 *   The outcome of this management policy is that the critical buffer is dedicated to the critical events, and the
 *   debug buffer is shared between critical and debug events.
 */

class EventManagement
{
public:
    /**
     * @brief
     * Initialize the EventManagement with an array of LogStorageResources.  The
     * array must provide a resource for each valid priority level, the elements
     * of the array must be in increasing numerical value of priority (and in
     * increasing priority); the first element in the array corresponds to the
     * resources allocated for least important events, and the last element
     * corresponds to the most critical events.
     *
     * @param[in] apExchangeManager         ExchangeManager to be used with this logging subsystem
     *
     * @param[in] aNumBuffers  Number of elements in inLogStorageResources array
     *
     * @param[in] apCircularEventBuffer  An array of CircularEventBuffer for each priority level.
     *
     * @param[in] apLogStorageResources  An array of LogStorageResources for each priority level.
     *
     * @param[in] apEventNumberCounter   A counter to use for event numbers.
     *
     */
    void Init(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers, CircularEventBuffer * apCircularEventBuffer,
              const LogStorageResources * const apLogStorageResources,
              MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter);

    static EventManagement & GetInstance();

    /**
     * @brief Create EventManagement object and initialize the logging management
     *   subsystem with provided resources.
     *
     * Initialize the EventManagement with an array of LogStorageResources.  The
     * array must provide a resource for each valid priority level, the elements
     * of the array must be in increasing numerical value of priority (and in
     * decreasing priority); the first element in the array corresponds to the
     * resources allocated for the most critical events, and the last element
     * corresponds to the least important events.
     *
     * @param[in] apExchangeManager         ExchangeManager to be used with this logging subsystem
     *
     * @param[in] aNumBuffers  Number of elements in inLogStorageResources array
     *
     * @param[in] apCircularEventBuffer  An array of CircularEventBuffer for each priority level.
     * @param[in] apLogStorageResources  An array of LogStorageResources for each priority level.
     *
     * @param[in] apEventNumberCounter   A counter to use for event numbers.
     *
     * @note This function must be called prior to the logging being used.
     */
    static void CreateEventManagement(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers,
                                      CircularEventBuffer * apCircularEventBuffer,
                                      const LogStorageResources * const apLogStorageResources,
                                      MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter);

    static void DestroyEventManagement();

    /**
     * @brief
     *   Log an event via a EventLoggingDelegate, with options.
     *
     * The EventLoggingDelegate writes the event metadata and calls the `apDelegate`
     * with an TLV::TLVWriter reference so that the user code can emit
     * the event data directly into the event log.  This form of event
     * logging minimizes memory consumption, as event data is serialized
     * directly into the target buffer.  The event data MUST contain
     * context tags to be interpreted within the schema identified by
     * `ClusterID` and `EventId`. The tag of the first element will be
     * ignored; the event logging system will replace it with the
     * eventData tag.
     *
     * The event is logged if the schema priority exceeds the logging
     * threshold specified in the LoggingConfiguration.  If the event's
     * priority does not meet the current threshold, it is dropped and
     * the function returns a `0` as the resulting event ID.
     *
     * This variant of the invocation permits the caller to set any
     * combination of `EventOptions`:
     * - timestamp, when 0 defaults to the current time at the point of
     *   the call,
     * - "root" section of the event source (event source and cluster ID);
     *   if NULL, it defaults to the current device. the event is marked as
     *   relating to the device that is making the call,
     *
     * @param[in] apDelegate The EventLoggingDelegate to serialize the event data
     *
     * @param[in] aEventOptions    The options for the event metadata.
     *
     * @param[out] aEventNumber The event Number if the event was written to the
     *                         log, 0 otherwise.
     *
     * @return CHIP_ERROR  CHIP Error Code
     */
    CHIP_ERROR LogEvent(EventLoggingDelegate * apDelegate, const EventOptions & aEventOptions, EventNumber & aEventNumber);

    /**
     * @brief
     *   A helper method to get tlv reader along with buffer has data from particular priority
     *
     * @param[in,out] aReader A reference to the reader that will be
     *                        initialized with the backing storage from
     *                        the event log
     *
     * @param[in] aPriority The starting priority for the reader.
     *                         Note that in this case the starting
     *                         priority is somewhat counter intuitive:
     *                         more important events share the buffers
     *                         with less priority events, in addition to
     *                         their dedicated buffers.  As a result, the
     *                         reader will traverse the least data when
     *                         the Debug priority is passed in.
     *
     * @param[in] apBufWrapper CircularEventBufferWrapper
     * @return                 #CHIP_NO_ERROR Unconditionally.
     */
    CHIP_ERROR GetEventReader(chip::TLV::TLVReader & aReader, PriorityLevel aPriority,
                              app::CircularEventBufferWrapper * apBufWrapper);

    /**
     * @brief
     *   A function to retrieve events of specified priority since a specified event ID.
     *
     * Given a TLV::TLVWriter, an priority type, and an event ID, the
     * function will fetch events since the
     * specified event number.  The function will continue fetching events until
     * it runs out of space in the TLV::TLVWriter or in the log. The function
     * will terminate the event writing on event boundary. The function would filter out event based upon interested path
     * specified by read/subscribe request.
     *
     * @param[in] aWriter     The writer to use for event storage
     * @param[in] apEventPathList the interested EventPathParams list
     *
     * @param[in,out] aEventMin On input, the Event number is the one we're fetching.  On
     *                         completion, the event number of the next one we plan to fetch.
     *
     * @param[out] aEventCount The number of fetched event
     * @param[in] aSubjectDescriptor Subject descriptor for current read handler
     * @retval #CHIP_END_OF_TLV             The function has reached the end of the
     *                                       available log entries at the specified
     *                                       priority level
     *
     * @retval #CHIP_ERROR_NO_MEMORY        The function ran out of space in the
     *                                       aWriter, more events in the log are
     *                                       available.
     *
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL The function ran out of space in the
     *                                       aWriter, more events in the log are
     *                                       available.
     *
     */
    CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, const ObjectList<EventPathParams> * apEventPathList,
                                EventNumber & aEventMin, size_t & aEventCount,
                                const Access::SubjectDescriptor & aSubjectDescriptor);
    /**
     * @brief brief Iterate all events and invalidate the fabric-sensitive events whose associated fabric has the given fabric
     * index.
     */
    CHIP_ERROR FabricRemoved(FabricIndex aFabricIndex);

    /**
     * @brief
     *   Fetch the most recently vended Number for a particular priority level
     *
     * @return EventNumber most recently vended event Number for that event priority
     */
    EventNumber GetLastEventNumber() const { return mLastEventNumber; }

    /**
     * @brief
     *   IsValid returns whether the EventManagement instance is valid
     */
    bool IsValid(void) { return EventManagementStates::Shutdown != mState; };

    /**
     *  Logger would save last logged event number and initial written event bytes number into schedule event number array
     */
    void SetScheduledEventInfo(EventNumber & aEventNumber, uint32_t & aInitialWrittenEventBytes) const;

private:
    /**
     * @brief
     *  Internal structure for traversing events.
     */
    struct EventEnvelopeContext
    {
        EventEnvelopeContext() {}

        int mFieldsToRead = 0;
        /* PriorityLevel and DeltaTime are there if that is not first event when putting events in report*/
#if CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS & CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME
        Timestamp mCurrentTime = Timestamp::System(System::Clock::kZero);
#else
        Timestamp mCurrentTime = Timestamp::Epoch(System::Clock::kZero);
#endif
        PriorityLevel mPriority  = PriorityLevel::First;
        ClusterId mClusterId     = 0;
        EndpointId mEndpointId   = 0;
        EventId mEventId         = 0;
        EventNumber mEventNumber = 0;
        Optional<FabricIndex> mFabricIndex;
    };

    void VendEventNumber();
    CHIP_ERROR CalculateEventSize(EventLoggingDelegate * apDelegate, const EventOptions * apOptions, uint32_t & requiredSize);
    /**
     * @brief Helper function for writing event header and data according to event
     *   logging protocol.
     *
     * @param[in,out] apContext EventLoadOutContext, initialized with stateful
     *                          information for the buffer. State is updated
     *                          and preserved by ConstructEvent using this context.
     *
     * @param[in] apDelegate The EventLoggingDelegate to serialize the event data
     *
     * @param[in] apOptions     EventOptions describing timestamp and other tags
     *                          relevant to this event.
     *
     */
    CHIP_ERROR ConstructEvent(EventLoadOutContext * apContext, EventLoggingDelegate * apDelegate, const EventOptions * apOptions);

    // Internal function to log event
    CHIP_ERROR LogEventPrivate(EventLoggingDelegate * apDelegate, const EventOptions & aEventOptions, EventNumber & aEventNumber);

    /**
     * @brief copy the event outright to next buffer with higher priority
     *
     * @param[in] apEventBuffer  CircularEventBuffer
     *
     */
    CHIP_ERROR CopyToNextBuffer(CircularEventBuffer * apEventBuffer);

    /**
     * @brief eusure current buffer has enough space, if not, when current buffer is final destination of last tail's event
     * priority, we need to drop event, otherwises, move the last event to the buffer with higher priority
     *
     * @param[in] aRequiredSpace  require space
     *
     */
    CHIP_ERROR EnsureSpaceInCircularBuffer(size_t aRequiredSpace);

    /**
     * @brief Iterate the event elements inside event tlv and mark the fabric index as kUndefinedFabricIndex if
     * it matches the FabricIndex apFabricIndex points to.
     *
     * @param[in] aReader  event tlv reader
     * @param[in] apFabricIndex   A FabricIndex* pointing to the fabric index for which we want to effectively evict events.
     *
     */
    static CHIP_ERROR FabricRemovedCB(const TLV::TLVReader & aReader, size_t, void * apFabricIndex);

    /**
     * @brief
     *   Internal API used to implement #FetchEventsSince
     *
     * Iterator function to used to copy an event from the log into a
     * TLVWriter. The included apContext contains the context of the copy
     * operation, including the TLVWriter that will hold the copy of an
     * event.  If event cannot be written as a whole, the TLVWriter will
     * be rolled back to event boundary.
     *
     * @retval #CHIP_END_OF_TLV             Function reached the end of the event
     * @retval #CHIP_ERROR_NO_MEMORY        Function could not write a portion of
     *                                       the event to the TLVWriter.
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL Function could not write a
     *                                       portion of the event to the TLVWriter.
     */
    static CHIP_ERROR CopyEventsSince(const TLV::TLVReader & aReader, size_t aDepth, void * apContext);

    /**
     * @brief Internal iterator function used to scan and filter though event logs
     *
     * The function is used to scan through the event log to find events matching the spec in the supplied context.
     * Particularly, it would check against mStartingEventNumber, and skip fetched event.
     */
    static CHIP_ERROR EventIterator(const TLV::TLVReader & aReader, size_t aDepth, EventLoadOutContext * apEventLoadOutContext,
                                    EventEnvelopeContext * event);

    /**
     * @brief Internal iterator function used to fetch event into EventEnvelopeContext, then EventIterator would filter event
     * based upon EventEnvelopeContext
     *
     */
    static CHIP_ERROR FetchEventParameters(const TLV::TLVReader & aReader, size_t aDepth, void * apContext);

    /**
     * @brief Internal iterator function used to scan and filter though event logs
     * First event gets a timestamp, subsequent ones get a delta T
     * First event in the sequence gets a event number neatly packaged
     */
    static CHIP_ERROR CopyAndAdjustDeltaTime(const TLV::TLVReader & aReader, size_t aDepth, void * apContext);

    /**
     * @brief checking if the tail's event can be moved to higher priority, if not, dropped, if yes, note how much space it
     * requires, and return.
     */
    static CHIP_ERROR EvictEvent(chip::TLV::CHIPCircularTLVBuffer & aBuffer, void * apAppData, TLV::TLVReader & aReader);
    static CHIP_ERROR AlwaysFail(chip::TLV::CHIPCircularTLVBuffer & aBuffer, void * apAppData, TLV::TLVReader & aReader)
    {
        return CHIP_ERROR_NO_MEMORY;
    };

    /**
     * @brief Check whether the event instance represented by the EventEnvelopeContext should be included in the report.
     *
     * @retval CHIP_ERROR_UNEXPECTED_EVENT This path should be excluded in the generated event report.
     * @retval CHIP_EVENT_ID_FOUND This path should be included in the generated event report.
     * @retval CHIP_ERROR_ACCESS_DENIED This path should be included in the generated event report, but the client does not have
     * .       enough privilege to access it.
     *
     * TODO: Consider using CHIP_NO_ERROR, CHIP_ERROR_SKIP_EVENT, CHIP_ERROR_ACCESS_DENINED or some enum to represent the checking
     * result.
     */
    static CHIP_ERROR CheckEventContext(EventLoadOutContext * eventLoadOutContext, const EventEnvelopeContext & event);

    /**
     * @brief copy event from circular buffer to target buffer for report
     */
    static CHIP_ERROR CopyEvent(const TLV::TLVReader & aReader, TLV::TLVWriter & aWriter, EventLoadOutContext * apContext);

    /**
     * @brief
     *   A function to get the circular buffer for particular priority
     *
     * @param aPriority PriorityLevel
     *
     * @return A pointer for the CircularEventBuffer
     */
    CircularEventBuffer * GetPriorityBuffer(PriorityLevel aPriority) const;

    // EventBuffer for debug level,
    CircularEventBuffer * mpEventBuffer        = nullptr;
    Messaging::ExchangeManager * mpExchangeMgr = nullptr;
    EventManagementStates mState               = EventManagementStates::Shutdown;
    uint32_t mBytesWritten                     = 0;

    // The counter we're going to use for event numbers.
    MonotonicallyIncreasingCounter<EventNumber> * mpEventNumberCounter = nullptr;

    EventNumber mLastEventNumber = 0; ///< Last event Number vended
    Timestamp mLastEventTimestamp;    ///< The timestamp of the last event in this buffer
};
} // namespace app
} // namespace chip
