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

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
                 >;

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; }

    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
