/*
 *
 *    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
 *      DeviceControllerSystemState is a representation of all the runtime state
 *      inside of CHIP that can be shared across Controllers and Commissioners.
 *
 *      The System State assumes it's being owned by and managed by the DeviceControllerFactory.
 *      It will automatically shutdown the underlying CHIP Stack when its reference count
 *      decreases to "1".
 *
 */

#pragma once

#include <app/CASEClientPool.h>
#include <app/CASESessionManager.h>
#include <app/reporting/ReportScheduler.h>
#include <credentials/FabricTable.h>
#include <credentials/GroupDataProvider.h>
#include <crypto/SessionKeystore.h>
#include <lib/core/CHIPConfig.h>
#include <protocols/bdx/BdxTransferServer.h>
#include <protocols/secure_channel/CASEServer.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
#include <protocols/secure_channel/UnsolicitedStatusHandler.h>

#include <transport/TransportMgr.h>
#include <transport/raw/UDP.h>
#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
#endif

#if CONFIG_NETWORK_LAYER_BLE
#include <ble/Ble.h>
#include <transport/raw/BLE.h>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
#include <transport/raw/WiFiPAF.h>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
#include <transport/raw/NFC.h>
#endif

namespace chip {

inline constexpr size_t kMaxDeviceTransportBlePendingPackets = 1;
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
inline constexpr size_t kMaxDeviceTransportWiFiPAFPendingPackets = 1;
#endif

#if INET_CONFIG_ENABLE_TCP_ENDPOINT
inline constexpr size_t kMaxDeviceTransportTcpActiveConnectionCount = CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS;

inline constexpr size_t kMaxDeviceTransportTcpPendingPackets = CHIP_CONFIG_MAX_TCP_PENDING_PACKETS;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT

using DeviceTransportMgr =
    TransportMgr<Transport::UDP /* IPv6 */
#if INET_CONFIG_ENABLE_IPV4
                 ,
                 Transport::UDP /* IPv4 */
#endif
#if CONFIG_NETWORK_LAYER_BLE
                 ,
                 Transport::BLE<kMaxDeviceTransportBlePendingPackets> /* BLE */
#endif
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
                 ,
                 Transport::TCP<kMaxDeviceTransportTcpActiveConnectionCount, kMaxDeviceTransportTcpPendingPackets>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
                 ,
                 Transport::WiFiPAF<kMaxDeviceTransportWiFiPAFPendingPackets> /* WiFiPAF */
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
                 ,
                 Transport::NFC /* NFC */
#endif
                 >;

namespace Controller {

struct DeviceControllerSystemStateParams
{
    using SessionSetupPool = OperationalSessionSetupPool<CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES>;
    using CASEClientPool   = chip::CASEClientPool<CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_CASE_CLIENTS>;

    // Params that can outlive the DeviceControllerSystemState
    System::Layer * systemLayer                                   = nullptr;
    Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager = nullptr;
    Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager = nullptr;
    FabricTable * fabricTable                                     = nullptr;
#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * bleLayer = nullptr;
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
    WiFiPAF::WiFiPAFLayer * wifipaf_layer = nullptr;
#endif
    Credentials::GroupDataProvider * groupDataProvider = nullptr;
    Crypto::SessionKeystore * sessionKeystore          = nullptr;

    // NOTE: Exactly one of externalSessionResumptionStorage (externally provided,
    // externally owned) or ownedSessionResumptionStorage (managed by the system
    // state) must be non-null.
    SessionResumptionStorage * externalSessionResumptionStorage = nullptr;

    // Params that will be deallocated via Platform::Delete in
    // DeviceControllerSystemState::Shutdown.
    DeviceTransportMgr * transportMgr = nullptr;
    // NOTE: Exactly one of externalSessionResumptionStorage (externally provided,
    // externally owned) or ownedSessionResumptionStorage (managed by the system
    // state) must be non-null.
    Platform::UniquePtr<SimpleSessionResumptionStorage> ownedSessionResumptionStorage;
    Credentials::CertificateValidityPolicy * certificateValidityPolicy            = nullptr;
    SessionManager * sessionMgr                                                   = nullptr;
    Protocols::SecureChannel::UnsolicitedStatusHandler * unsolicitedStatusHandler = nullptr;
    Messaging::ExchangeManager * exchangeMgr                                      = nullptr;
    secure_channel::MessageCounterManager * messageCounterManager                 = nullptr;
    bdx::BDXTransferServer * bdxTransferServer                                    = nullptr;
    CASEServer * caseServer                                                       = nullptr;
    CASESessionManager * caseSessionManager                                       = nullptr;
    SessionSetupPool * sessionSetupPool                                           = nullptr;
    CASEClientPool * caseClientPool                                               = nullptr;
    FabricTable::Delegate * fabricTableDelegate                                   = nullptr;
    chip::app::reporting::ReportScheduler::TimerDelegate * timerDelegate          = nullptr;
    chip::app::reporting::ReportScheduler * reportScheduler                       = nullptr;
};

// A representation of the internal state maintained by the DeviceControllerFactory.
//
// This class automatically maintains a count of active device controllers and
// shuts down Matter when there are none remaining.
//
// NB: Lifetime of the object itself is not managed by reference counting; it is
// owned by DeviceControllerFactory.
class DeviceControllerSystemState
{
    using SessionSetupPool = DeviceControllerSystemStateParams::SessionSetupPool;
    using CASEClientPool   = DeviceControllerSystemStateParams::CASEClientPool;

public:
    ~DeviceControllerSystemState()
    {
        // We could get here if a DeviceControllerFactory is shut down
        // without ever creating any controllers, so our refcount never goes
        // above 1.  In that case we need to make sure we call Shutdown().
        Shutdown();
    };

    DeviceControllerSystemState(DeviceControllerSystemStateParams params) :
        mSystemLayer(params.systemLayer), mTCPEndPointManager(params.tcpEndPointManager),
        mUDPEndPointManager(params.udpEndPointManager), mTransportMgr(params.transportMgr), mSessionMgr(params.sessionMgr),
        mUnsolicitedStatusHandler(params.unsolicitedStatusHandler), mExchangeMgr(params.exchangeMgr),
        mMessageCounterManager(params.messageCounterManager), mFabrics(params.fabricTable),
        mBDXTransferServer(params.bdxTransferServer), mCASEServer(params.caseServer),
        mCASESessionManager(params.caseSessionManager), mSessionSetupPool(params.sessionSetupPool),
        mCASEClientPool(params.caseClientPool), mGroupDataProvider(params.groupDataProvider), mTimerDelegate(params.timerDelegate),
        mReportScheduler(params.reportScheduler), mSessionKeystore(params.sessionKeystore),
        mFabricTableDelegate(params.fabricTableDelegate),
        mOwnedSessionResumptionStorage(std::move(params.ownedSessionResumptionStorage))
    {
        if (mOwnedSessionResumptionStorage)
        {
            mSessionResumptionStorage = mOwnedSessionResumptionStorage.get();
        }
        else
        {
            mSessionResumptionStorage = params.externalSessionResumptionStorage;
        }

#if CONFIG_NETWORK_LAYER_BLE
        mBleLayer = params.bleLayer;
#endif
        VerifyOrDie(IsInitialized());
    };

    // Acquires a reference to the system state.
    //
    // While a reference is held, the shared state is kept alive. Release()
    // should be called to release the reference once it is no longer needed.
    DeviceControllerSystemState * Retain()
    {
        auto count = mRefCount++;
        VerifyOrDie(count < std::numeric_limits<decltype(count)>::max()); // overflow
        VerifyOrDie(!IsShutDown());                                       // avoid zombie
        return this;
    };

    // Releases a reference to the system state.
    //
    // The stack will shut down when all references are released.
    //
    // NB: The system state is owned by the factory; Release() will not free it
    // but will free its members (Shutdown()).
    //
    // Returns true if the system state was shut down in response to this call.
    bool Release()
    {
        auto count = mRefCount--;
        VerifyOrDie(count > 0); // underflow
        VerifyOrReturnValue(count == 1, false);
        Shutdown();
        return true;
    };
    bool IsInitialized()
    {
        return mSystemLayer != nullptr && mUDPEndPointManager != nullptr && mTransportMgr != nullptr && mSessionMgr != nullptr &&
            mUnsolicitedStatusHandler != nullptr && mExchangeMgr != nullptr && mMessageCounterManager != nullptr &&
            mFabrics != nullptr && mCASESessionManager != nullptr && mSessionSetupPool != nullptr && mCASEClientPool != nullptr &&
            mGroupDataProvider != nullptr && mReportScheduler != nullptr && mTimerDelegate != nullptr &&
            mSessionKeystore != nullptr && mSessionResumptionStorage != nullptr && mBDXTransferServer != nullptr;
    };
    bool IsShutDown() const { return mHaveShutDown; }

    System::Layer * SystemLayer() const { return mSystemLayer; };
    Inet::EndPointManager<Inet::TCPEndPoint> * TCPEndPointManager() const { return mTCPEndPointManager; };
    Inet::EndPointManager<Inet::UDPEndPoint> * UDPEndPointManager() const { return mUDPEndPointManager; };
    DeviceTransportMgr * TransportMgr() const { return mTransportMgr; };
    SessionManager * SessionMgr() const { return mSessionMgr; };
    Messaging::ExchangeManager * ExchangeMgr() const { return mExchangeMgr; }
    secure_channel::MessageCounterManager * MessageCounterManager() const { return mMessageCounterManager; };
    FabricTable * Fabrics() const { return mFabrics; };
#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * BleLayer() const { return mBleLayer; };
#endif
    CASESessionManager * CASESessionMgr() const { return mCASESessionManager; }
    Credentials::GroupDataProvider * GetGroupDataProvider() const { return mGroupDataProvider; }
    chip::app::reporting::ReportScheduler * GetReportScheduler() const { return mReportScheduler; }
    SessionResumptionStorage * GetSessionResumptionStorage() const { return mSessionResumptionStorage; }

    Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; }
    void SetTempFabricTable(FabricTable * tempFabricTable, bool enableServerInteractions)
    {
        mTempFabricTable          = tempFabricTable;
        mEnableServerInteractions = enableServerInteractions;
    }
    bdx::BDXTransferServer * BDXTransferServer() const { return mBDXTransferServer; }

private:
    DeviceControllerSystemState() {}

    System::Layer * mSystemLayer                                   = nullptr;
    Inet::EndPointManager<Inet::TCPEndPoint> * mTCPEndPointManager = nullptr;
    Inet::EndPointManager<Inet::UDPEndPoint> * mUDPEndPointManager = nullptr;
#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * mBleLayer = nullptr;
#endif
    DeviceTransportMgr * mTransportMgr                                             = nullptr;
    SessionManager * mSessionMgr                                                   = nullptr;
    Protocols::SecureChannel::UnsolicitedStatusHandler * mUnsolicitedStatusHandler = nullptr;
    Messaging::ExchangeManager * mExchangeMgr                                      = nullptr;
    secure_channel::MessageCounterManager * mMessageCounterManager                 = nullptr;
    FabricTable * mFabrics                                                         = nullptr;
    bdx::BDXTransferServer * mBDXTransferServer                                    = nullptr;
    CASEServer * mCASEServer                                                       = nullptr;
    CASESessionManager * mCASESessionManager                                       = nullptr;
    SessionSetupPool * mSessionSetupPool                                           = nullptr;
    CASEClientPool * mCASEClientPool                                               = nullptr;
    Credentials::GroupDataProvider * mGroupDataProvider                            = nullptr;
    app::reporting::ReportScheduler::TimerDelegate * mTimerDelegate                = nullptr;
    app::reporting::ReportScheduler * mReportScheduler                             = nullptr;
    Crypto::SessionKeystore * mSessionKeystore                                     = nullptr;
    FabricTable::Delegate * mFabricTableDelegate                                   = nullptr;
    SessionResumptionStorage * mSessionResumptionStorage                           = nullptr;
    Platform::UniquePtr<SimpleSessionResumptionStorage> mOwnedSessionResumptionStorage;

    // If mTempFabricTable is not null, it was created during
    // DeviceControllerFactory::InitSystemState and needs to be
    // freed during shutdown
    FabricTable * mTempFabricTable = nullptr;

    std::atomic<uint32_t> mRefCount{ 0 };

    bool mHaveShutDown = false;

    bool mEnableServerInteractions = false;

    void Shutdown();
};

} // namespace Controller
} // namespace chip
