/*
 *
 *    Copyright (c) 2023 Project CHIP Authors
 *
 *    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 <app/icd/server/ICDServerConfig.h>

#include <app/AppConfig.h>
#include <app/SubscriptionsInfoProvider.h>
#include <app/TestEventTriggerDelegate.h>
#include <app/icd/server/ICDConfigurationData.h>
#include <app/icd/server/ICDNotifier.h>
#include <app/icd/server/ICDStateObserver.h>
#include <credentials/FabricTable.h>
#include <crypto/SessionKeystore.h>
#include <lib/support/BitFlags.h>
#include <messaging/ExchangeMgr.h>
#include <platform/CHIPDeviceConfig.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <system/SystemClock.h>

#if CHIP_CONFIG_ENABLE_ICD_CIP
#include <app/icd/server/ICDCheckInSender.h>   // nogncheck
#include <app/icd/server/ICDMonitoringTable.h> // nogncheck
#endif                                         // CHIP_CONFIG_ENABLE_ICD_CIP

namespace chip {
namespace Crypto {
using SymmetricKeystore = SessionKeystore;
}
} // namespace chip

namespace chip {
namespace app {

// Forward declaration of TestICDManager tests to allow it to be friend with ICDManager
// Used in unit tests
class TestICDManager_TestShouldCheckInMsgsBeSentAtActiveModeFunction_Test;

/**
 * @brief ICD Manager is responsible of processing the events and triggering the correct action for an ICD
 */
class ICDManager : public ICDListener, public TestEventTriggerHandler
{
public:
    /**
     * @brief This structure is used for the creation an ObjectPool of ICDStateObserver pointers
     */
    struct ObserverPointer
    {
        ObserverPointer(ICDStateObserver * obs) : mObserver(obs) {}
        ~ObserverPointer() { mObserver = nullptr; }
        ICDStateObserver * mObserver;
    };

    enum class OperationalState : uint8_t
    {
        IdleMode,
        ActiveMode,
    };

    /**
     * @brief This enum class represents all ICDStateObserver callbacks available from the
     *        mStateObserverPool for the ICDManager.
     *
     *        EnterActiveMode, TransitionToIdle and EnterIdleMode will always be called as a trio in the same order.
     *        Each event will only be called once per cycle.
     *        EnterActiveMode will always be called first, when the ICD has transitioned to ActiveMode.
     *        TransitionToIdle will always be second. This event will only be called the first time there is
     *        `ICD_ACTIVE_TIME_JITTER_MS` remaining to the ActiveMode timer.
     *         When this event is called, the ICD is still in ActiveMode.
     *        If the ActiveMode timer is increased due to the TransitionToIdle event, the event will not be called a second time in
     *        a given cycle.
     *        OnEnterIdleMode will always the third event and indicates that the ICD has transitioned to IdleMode.
     *
     *        The ICDModeChange event can occur independently from the EnterActiveMode, TransitionToIdle and EnterIdleMode.
     *        It will typically happen at the ICDManager init when a client is already registered with the ICD before the
     *        OnEnterIdleMode event or when a client sends a register command after the OnEnterActiveMode event. Nothing prevents
     *        the ICDModeChange event from happening multiple times per cycle or while the ICD is in IdleMode.
     *
     *        See src/app/icd/server/ICDStateObserver.h for more information on the APIs each event triggers
     */
    enum class ObserverEventType : uint8_t
    {
        EnterActiveMode,
        EnterIdleMode,
        TransitionToIdle,
        ICDModeChange,
    };

    /**
     * @brief Verifier template function
     *        This type can be used to implement specific verifiers that can be used in the CheckInMessagesWouldBeSent function.
     *        The goal is to avoid having multiple functions that implement the iterator loop with only the check changing.
     *
     * @return true: if at least one Check-In message would be sent
     *         false: No Check-In messages would be sent
     */
    using ShouldCheckInMsgsBeSentFunction = bool(FabricIndex aFabricIndex, NodeId subjectID);

    ICDManager()  = default;
    ~ICDManager() = default;

    void Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, Crypto::SymmetricKeystore * symmetricKeyStore,
              Messaging::ExchangeManager * exchangeManager, SubscriptionsInfoProvider * subInfoProvider);
    void Shutdown();

    /**
     * @brief SupportsFeature verifies if a given FeatureMap bit is enabled
     *
     * @param[in] feature FeatureMap bit to verify
     *
     * @return true: if the FeatureMap bit is enabled in the ICDM cluster attribute.
     *         false: if the FeatureMap bit is not enabled in the ICDM cluster attribute.
     *                if we failed to read the FeatureMap attribute.
     */
    bool SupportsFeature(Clusters::IcdManagement::Feature feature);

    ICDConfigurationData::ICDMode GetICDMode() { return ICDConfigurationData::GetInstance().GetICDMode(); };

    OperationalState GetOperaionalState() { return mOperationalState; };

    /**
     * @brief Adds the referenced observer in parameters to the mStateObserverPool
     * A maximum of CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE observers can be concurrently registered
     *
     * @return The pointer to the pool object, or null if it could not be added.
     */
    ObserverPointer * RegisterObserver(ICDStateObserver * observer);

    /**
     * @brief Remove the referenced observer in parameters from the mStateObserverPool
     *        If the observer is not present in the object pool, we do nothing
     */
    void ReleaseObserver(ICDStateObserver * observer);

    /**
     * @brief Ensures that the remaining Active Mode duration is at least the smaller of 30000 milliseconds and stayActiveDuration.
     *
     * @param[in] stayActiveDuration The duration (in milliseconds) requested by the client to stay in Active Mode
     * @return The duration (in milliseconds) the device will stay in Active Mode
     */
    uint32_t StayActiveRequest(uint32_t stayActiveDuration);

    /**
     * @brief TestEventTriggerHandler for the ICD feature set
     *
     * @param[in] eventTrigger Event trigger to handle.
     *
     * @return CHIP_ERROR CHIP_NO_ERROR - No erros during the processing
     *                    CHIP_ERROR_INVALID_ARGUMENT - eventTrigger isn't a valid value
     */
    CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override;

#if CHIP_CONFIG_ENABLE_ICD_CIP
    /**
     * @brief Trigger the ICDManager to send Check-In message if necessary
     *
     * @param[in] function to use to determine if we need to send check-in messages
     */
    void TriggerCheckInMessages(const std::function<ShouldCheckInMsgsBeSentFunction> & function);

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    /**
     * @brief Set mSubCheckInBootCheckExecuted to true
     *        Function allows the InteractionModelEngine to notify the ICDManager that the boot up subscription resumption has been
     *        completed.
     */
    void SetBootUpResumeSubscriptionExecuted() { mIsBootUpResumeSubscriptionExecuted = true; };
#endif // !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    void SetTestFeatureMapValue(uint32_t featureMap) { mFeatureMap = featureMap; };
#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    bool GetIsBootUpResumeSubscriptionExecuted() { return mIsBootUpResumeSubscriptionExecuted; };
#endif // !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
#endif

    // Implementation of ICDListener functions.
    // Callers must origin from the chip task context or hold the ChipStack lock.

    void OnNetworkActivity() override;
    void OnKeepActiveRequest(KeepActiveFlags request) override;
    void OnActiveRequestWithdrawal(KeepActiveFlags request) override;
    void OnICDManagementServerEvent(ICDManagementEvents event) override;
    void OnSubscriptionReport() override;

private:
    // TODO : Once <gtest/gtest_prod.h> can be included, use FRIEND_TEST for the friend class.
    friend class TestICDManager_TestShouldCheckInMsgsBeSentAtActiveModeFunction_Test;

    /**
     * @brief UpdateICDMode evaluates in which mode the ICD can be in; SIT or LIT mode.
     *        If the current operating mode does not match the evaluated operating mode, function updates the ICDMode and triggers
     *        all necessary operations.
     *        For a SIT ICD, this function does nothing.
     *        For a LIT ICD, the function checks if the ICD has a registration in the ICDMonitoringTable to determine which ICDMode
     *        the ICD must be in.
     */
    void UpdateICDMode();

    /**
     * @brief UpdateOperationState updates the OperationState of the ICD to the requested one.
     *        IdleMode -> IdleMode     : No actions are necessary, do nothing.
     *        IdleMode -> ActiveMode   : Transition the device to ActiveMode, start the  ActiveMode timer and trigger all necessary
     *                                   operations. These operations could be : Send Check-In messages
     *                                                                           Send subscription reports
     *                                                                           Process user actions
     *        ActiveMode -> ActiveMode : Increase remaining ActiveMode timer to one ActiveModeThreshold.
     *                                   If ActiveModeThreshold is 0, do nothing.
     *        ActiveMode -> IdleMode   : Transition ICD to IdleMode and start the IdleMode timer.
     *
     * @param state requested OperationalState for the ICD to transition to
     */
    void UpdateOperationState(OperationalState state);

    /**
     * @brief Set or Remove a keep ActiveMode requirement for the given flag
     *        If state is true and the ICD is in IdleMode, transition the ICD to ActiveMode
     *        If state is false and the ICD is in ActiveMode, check whether we can transition the ICD to IdleMode.
     *        If we can, transition the ICD to IdleMode.
     *
     * @param flag KeepActiveFlag to remove or add
     * @param state true: adding a flag requirement
     *              false: removing a flag requirement
     */
    void SetKeepActiveModeRequirements(KeepActiveFlags flag, bool state);

    /**
     * @brief Associates the ObserverEventType parameters to the correct
     *  ICDStateObservers function and calls it for all observers in the mStateObserverPool
     */
    void postObserverEvent(ObserverEventType event);

    /**
     * @brief Hepler function that extends the ActiveMode timer as well as the Active Mode Jitter timer for the transition to
     *        idle mode event.
     */
    void ExtendActiveMode(System::Clock::Milliseconds16 extendDuration);

    /**
     * @brief Timer callback function for when the IdleMode timer expires
     *
     * @param appState pointer to the ICDManager
     */
    static void OnIdleModeDone(System::Layer * aLayer, void * appState);

    /**
     * @brief Timer callback function for when the ActiveMode timer expires
     *
     * @param appState pointer to the ICDManager
     */
    static void OnActiveModeDone(System::Layer * aLayer, void * appState);

    /**
     * @brief Timer Callback function called shortly before the device enters idle mode to allow checks to be made.
     *        This is currently only called once to prevent entering in a loop if some events re-trigger this check (for instance if
     *        a check for subscriptions before entering idle mode leads to emiting a report, we will re-enter UpdateOperationState
     *        and check again for subscription, etc.)
     *
     * @param appState pointer to the ICDManager
     */
    static void OnTransitionToIdle(System::Layer * aLayer, void * appState);

#if CHIP_CONFIG_ENABLE_ICD_CIP
    /**
     * @brief Function triggers all necessary Check-In messages to be sent.
     *
     * @note For each ICDMonitoring entry, we check if should send a Check-In message with
     *       ShouldCheckInMsgsBeSentAtActiveModeFunction. If we should, we allocate an ICDCheckInSender which tries to send a
     *       Check-In message to the registered client.
     */
    void SendCheckInMsgs();

    /**
     * @brief See function implementation in .cpp for details on this function.
     */
    bool ShouldCheckInMsgsBeSentAtActiveModeFunction(FabricIndex aFabricIndex, NodeId subjectID);

    /**
     * @brief Function checks if at least one client registration would require a Check-In message
     *
     * @param[in] function  function to use to determine if a Check-In message would be sent for a given registration
     *
     * @return true At least one registration would require an Check-In message if we were entering ActiveMode.
     * @return false None of the registration would require a Check-In message either because there are no registration or
     * because they all have associated subscriptions.
     */
    bool CheckInMessagesWouldBeSent(const std::function<ShouldCheckInMsgsBeSentFunction> & function);
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

    KeepActiveFlags mKeepActiveFlags{ 0 };

    // Initialize mOperationalState to ActiveMode so the init sequence at bootup triggers the IdleMode behaviour first.
    OperationalState mOperationalState = OperationalState::ActiveMode;
    bool mTransitionToIdleCalled       = false;
    ObjectPool<ObserverPointer, CHIP_CONFIG_ICD_OBSERVERS_POOL_SIZE> mStateObserverPool;
    uint8_t mOpenExchangeContextCount = 0;

#if CHIP_CONFIG_ENABLE_ICD_CIP
    uint8_t mCheckInRequestCount = 0;

#if !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    bool mIsBootUpResumeSubscriptionExecuted = false;
#endif // !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS

    PersistentStorageDelegate * mStorage           = nullptr;
    FabricTable * mFabricTable                     = nullptr;
    Messaging::ExchangeManager * mExchangeManager  = nullptr;
    Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr;
    SubscriptionsInfoProvider * mSubInfoProvider   = nullptr;
    ObjectPool<ICDCheckInSender, (CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC * CHIP_CONFIG_MAX_FABRICS)> mICDSenderPool;
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

#ifdef CONFIG_BUILD_FOR_HOST_UNIT_TEST
    // feature map that can be changed at runtime for testing purposes
    uint32_t mFeatureMap = 0;
#endif
};

} // namespace app
} // namespace chip
