/*
 *
 *    Copyright (c) 2020-2022 Project CHIP Authors
 *    Copyright (c) 2013-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
 *      Declaration of CHIP Device Controller, a common class
 *      that implements connecting and messaging and will later
 *      be expanded to support discovery, pairing and
 *      provisioning of CHIP  devices.
 *
 */

#pragma once

#include <app/AppConfig.h>
#include <app/CASEClientPool.h>
#include <app/CASESessionManager.h>
#include <app/ClusterStateCache.h>
#include <app/OperationalSessionSetup.h>
#include <app/OperationalSessionSetupPool.h>
#include <controller/AbstractDnssdDiscoveryController.h>
#include <controller/AutoCommissioner.h>
#include <controller/CHIPCluster.h>
#include <controller/CHIPDeviceControllerSystemState.h>
#include <controller/CommissioneeDeviceProxy.h>
#include <controller/CommissioningDelegate.h>
#include <controller/DevicePairingDelegate.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <controller/SetUpCodePairer.h>
#include <credentials/FabricTable.h>
#include <credentials/attestation_verifier/DeviceAttestationDelegate.h>
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
#include <inet/InetInterface.h>
#include <lib/core/CHIPConfig.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPPersistentStorageDelegate.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/TLV.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>
#include <lib/support/SafeInt.h>
#include <lib/support/Span.h>
#include <lib/support/ThreadOperationalDataset.h>
#include <messaging/ExchangeMgr.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/RendezvousParameters.h>
#include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
#include <system/SystemClock.h>
#include <transport/SessionManager.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/BleLayer.h>
#endif
#include <controller/DeviceDiscoveryDelegate.h>

namespace chip {

namespace Controller {

using namespace chip::Protocols::UserDirectedCommissioning;

inline constexpr uint16_t kNumMaxActiveDevices = CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES;

struct ControllerInitParams
{
    DeviceControllerSystemState * systemState                       = nullptr;
    DeviceDiscoveryDelegate * deviceDiscoveryDelegate               = nullptr;
    OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;

    /* The following keypair must correspond to the public key used for generating
       controllerNOC. It's used by controller to establish CASE sessions with devices */
    Crypto::P256Keypair * operationalKeypair = nullptr;

    /**
     * Controls whether or not the operationalKeypair should be owned by the caller.
     * By default, this is false, but if the keypair cannot be serialized, then
     * setting this to true will allow the caller to manage this keypair's lifecycle.
     */
    bool hasExternallyOwnedOperationalKeypair = false;

    /* The following certificates must be in x509 DER format */
    ByteSpan controllerNOC;
    ByteSpan controllerICAC;
    ByteSpan controllerRCAC;

    /**
     * Controls whether we permit multiple DeviceController instances to exist
     * on the same logical fabric (identified by the tuple of the fabric's
     * root public key + fabric id).
     *
     * Each controller instance will be associated with its own FabricIndex.
     * This pivots the FabricTable to tracking identities instead of fabrics,
     * represented by FabricInfo instances that can have colliding logical fabrics.
     *
     */
    bool permitMultiControllerFabrics = false;

    //
    // Controls enabling server cluster interactions on a controller. This in turn
    // causes the following to get enabled:
    //
    //  - Advertisement of active controller operational identities.
    //
    bool enableServerInteractions = false;

    /**
     * Controls whether shutdown of the controller removes the corresponding
     * entry from the fabric table.  For now the removal is just from the
     * in-memory table, not from storage, which means that after controller
     * shutdown the storage and the in-memory fabric table will be out of sync.
     * This is acceptable for implementations that don't actually store any of
     * the fabric table information, but if someone wants a true removal at some
     * point another option will need to be added here.
     */
    bool removeFromFabricTableOnShutdown = true;

    chip::VendorId controllerVendorId;
};

struct CommissionerInitParams : public ControllerInitParams
{
    DevicePairingDelegate * pairingDelegate     = nullptr;
    CommissioningDelegate * defaultCommissioner = nullptr;
    // Device attestation verifier instance for the commissioning.
    // If null, the globally set attestation verifier (e.g. from GetDeviceAttestationVerifier()
    // singleton) will be used.
    Credentials::DeviceAttestationVerifier * deviceAttestationVerifier = nullptr;
};

/**
 * @brief
 *   Controller applications can use this class to communicate with already paired CHIP devices. The
 *   application is required to provide access to the persistent storage, where the paired device information
 *   is stored. This object of this class can be initialized with the data from the storage (List of devices,
 *   and device pairing information for individual devices). Alternatively, this class can retrieve the
 *   relevant information when the application tries to communicate with the device
 */
class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController
{
public:
    DeviceController();
    ~DeviceController() override {}

    CHIP_ERROR Init(ControllerInitParams params);

    /**
     * @brief
     *  Tears down the entirety of the stack, including destructing key objects in the system.
     *  This expects to be called with external thread synchronization, and will not internally
     *  grab the CHIP stack lock.
     *
     *  This will also not stop the CHIP event queue / thread (if one exists).  Consumers are expected to
     *  ensure this happened before calling this method.
     */
    virtual void Shutdown();

    SessionManager * SessionMgr()
    {
        if (mSystemState)
        {
            return mSystemState->SessionMgr();
        }

        return nullptr;
    }

    Messaging::ExchangeManager * ExchangeMgr()
    {
        if (mSystemState != nullptr)
        {
            return mSystemState->ExchangeMgr();
        }

        return nullptr;
    }

    CHIP_ERROR GetPeerAddressAndPort(NodeId peerId, Inet::IPAddress & addr, uint16_t & port);

    /**
     * @brief
     *   Looks up the PeerAddress for an established CASE session.
     *
     * @param[in] nodeId the NodeId of the target.
     * @param[out] addr the PeerAddress to be filled on success
     *
     * @return CHIP_ERROR CHIP_ERROR_NOT_CONNECTED if no CASE session exists for the device
     */
    CHIP_ERROR GetPeerAddress(NodeId nodeId, Transport::PeerAddress & addr);

    ScopedNodeId GetPeerScopedId(NodeId nodeId) { return ScopedNodeId(nodeId, GetFabricIndex()); }

    /**
     * This function finds the device corresponding to deviceId, and establishes
     * a CASE session with it.
     *
     * Once the CASE session is successfully established the `onConnection`
     * callback is called. This can happen before GetConnectedDevice returns if
     * there is an existing CASE session.
     *
     * If a CASE sessions fails to be established, the `onFailure` callback will
     * be called.  This can also happen before GetConnectedDevice returns.
     *
     * An error return from this function means that neither callback has been
     * called yet, and neither callback will be called in the future.
     */
    CHIP_ERROR GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
                                  chip::Callback::Callback<OnDeviceConnectionFailure> * onFailure)
    {
        VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
        mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, onFailure);
        return CHIP_NO_ERROR;
    }

    /**
     * This function finds the device corresponding to deviceId, and establishes
     * a CASE session with it.
     *
     * Once the CASE session is successfully established the `onConnection`
     * callback is called. This can happen before GetConnectedDevice returns if
     * there is an existing CASE session.
     *
     * If a CASE sessions fails to be established, the `onSetupFailure` callback will
     * be called.  This can also happen before GetConnectedDevice returns.
     *
     * An error return from this function means that neither callback has been
     * called yet, and neither callback will be called in the future.
     */
    CHIP_ERROR
    GetConnectedDevice(NodeId peerNodeId, Callback::Callback<OnDeviceConnected> * onConnection,
                       chip::Callback::Callback<OperationalSessionSetup::OnSetupFailure> * onSetupFailure)
    {
        VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
        mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection,
                                                               onSetupFailure);
        return CHIP_NO_ERROR;
    }

    /**
     * @brief
     *   Compute a PASE verifier and passcode ID for the desired setup pincode.
     *
     *   This can be used to open a commissioning window on the device for
     *   additional administrator commissioning.
     *
     * @param[in] iterations      The number of iterations to use when generating the verifier
     * @param[in] setupPincode    The desired PIN code to use
     * @param[in] salt            The 16-byte salt for verifier computation
     * @param[out] outVerifier    The Spake2pVerifier to be populated on success
     *
     * @return CHIP_ERROR         CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR ComputePASEVerifier(uint32_t iterations, uint32_t setupPincode, const ByteSpan & salt,
                                   Spake2pVerifier & outVerifier);

    void RegisterDeviceDiscoveryDelegate(DeviceDiscoveryDelegate * delegate) { mDeviceDiscoveryDelegate = delegate; }

    /**
     * @brief Get the Compressed Fabric ID assigned to the device.
     */
    uint64_t GetCompressedFabricId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetCompressedFabricId()) : kUndefinedCompressedFabricId;
    }

    /**
     * @brief Get the Compressed Fabric Id as a big-endian 64 bit octet string.
     *
     * Output span is resized to 8 bytes on success if it was larger.
     *
     * @param outBytes span to contain the compressed fabric ID, must be at least 8 bytes long
     * @return CHIP_ERROR_BUFFER_TOO_SMALL if `outBytes` is too small, CHIP_ERROR_INVALID_FABRIC_INDEX
     *         if the controller is somehow not associated with a fabric (internal error!) or
     *         CHIP_NO_ERROR on success.
     */
    CHIP_ERROR GetCompressedFabricIdBytes(MutableByteSpan & outBytes) const;

    /**
     * @brief Get the raw Fabric ID assigned to the device.
     */
    uint64_t GetFabricId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetFabricId()) : kUndefinedFabricId;
    }

    /**
     * @brief Get the Node ID of this instance.
     */
    NodeId GetNodeId() const
    {
        const auto * fabricInfo = GetFabricInfo();
        return (fabricInfo != nullptr) ? static_cast<uint64_t>(fabricInfo->GetNodeId()) : kUndefinedNodeId;
    }

    /**
     * @brief Get the root public key for the fabric
     *
     * @param outRootPublicKey reference to public key object that gets updated on success.
     *
     * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if fabric table is unset, or another internal error
     *         on storage access failure.
     */
    CHIP_ERROR GetRootPublicKey(Crypto::P256PublicKey & outRootPublicKey) const;

    FabricIndex GetFabricIndex() const { return mFabricIndex; }

    const FabricTable * GetFabricTable() const
    {
        if (mSystemState == nullptr)
        {
            return nullptr;
        }
        return mSystemState->Fabrics();
    }

    OperationalCredentialsDelegate * GetOperationalCredentialsDelegate() { return mOperationalCredentialsDelegate; }

    /**
     * @brief
     *   Reconfigures a new set of operational credentials to be used with this
     *   controller given ControllerInitParams state.
     *
     * WARNING: This is a low-level method that should only be called directly
     *          if you know exactly how this will interact with controller state,
     *          since there are several integrations that do this call for you.
     *          It can be used for fine-grained dependency injection of a controller's
     *          NOC and operational keypair.
     */
    CHIP_ERROR InitControllerNOCChain(const ControllerInitParams & params);

protected:
    enum class State
    {
        NotInitialized,
        Initialized
    };

    // This is not public to avoid users of DeviceController relying on "innards" access to
    // the raw fabric table. Everything needed should be available with getters on DeviceController.
    const FabricInfo * GetFabricInfo() const
    {
        VerifyOrReturnError((mState == State::Initialized) && (mFabricIndex != kUndefinedFabricIndex), nullptr);
        VerifyOrReturnError(GetFabricTable() != nullptr, nullptr);

        return GetFabricTable()->FindFabricWithIndex(mFabricIndex);
    }

    State mState;

    FabricIndex mFabricIndex = kUndefinedFabricIndex;

    bool mRemoveFromFabricTableOnShutdown = true;

    // TODO(cecille): Make this configuarable.
    static constexpr int kMaxCommissionableNodes = 10;
    Dnssd::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes];
    DeviceControllerSystemState * mSystemState = nullptr;

    ControllerDeviceInitParams GetControllerDeviceInitParams();

    OperationalCredentialsDelegate * mOperationalCredentialsDelegate;

    chip::VendorId mVendorId;

    DiscoveredNodeList GetDiscoveredNodes() override { return DiscoveredNodeList(mCommissionableNodes); }
};

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
#if INET_CONFIG_ENABLE_IPV4
                                     ,
                                     Transport::UDP /* IPv4 */
#endif
                                     >;
#endif

/**
 * @brief Callback prototype for ExtendArmFailSafe command.
 */
typedef void (*OnExtendFailsafeSuccess)(
    void * context, const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
typedef void (*OnExtendFailsafeFailure)(void * context, CHIP_ERROR error);

/**
 * @brief
 *   The commissioner applications can use this class to pair new/unpaired CHIP devices. The application is
 *   required to provide write access to the persistent storage, where the paired device information
 *   will be stored.
 */
class DLL_EXPORT DeviceCommissioner : public DeviceController,
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
                                      public Protocols::UserDirectedCommissioning::InstanceNameResolver,
#endif
#if CHIP_CONFIG_ENABLE_READ_CLIENT
                                      public app::ClusterStateCache::Callback,
#endif
                                      public SessionEstablishmentDelegate
{
public:
    DeviceCommissioner();
    ~DeviceCommissioner() override {}

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    /**
     * Set port for User Directed Commissioning
     */
    CHIP_ERROR SetUdcListenPort(uint16_t listenPort);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

    /**
     * Commissioner-specific initialization, includes parameters such as the pairing delegate.
     */
    CHIP_ERROR Init(CommissionerInitParams params);

    /**
     * @brief
     *  Tears down the entirety of the stack, including destructing key objects in the system.
     *  This is not a thread-safe API, and should be called with external synchronization.
     *
     *  Please see implementation for more details.
     */
    void Shutdown() override;

    // ----- Connection Management -----
    /**
     * @brief
     *   Pair a CHIP device with the provided code. The code can be either a QRCode
     *   or a Manual Setup Code.
     *   Use registered DevicePairingDelegate object to receive notifications on
     *   pairing status updates.
     *
     *   Note: Pairing process requires that the caller has registered PersistentStorageDelegate
     *         in the Init() call.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] setUpCode             The setup code for connecting to the device
     * @param[in] discoveryType         The network discovery type, defaults to DiscoveryType::kAll.
     * @param[in] resolutionData        Optional resolution data previously discovered on the network for the target device.
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, DiscoveryType discoveryType = DiscoveryType::kAll,
                          Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, const char * setUpCode, const CommissioningParameters & CommissioningParameters,
                          DiscoveryType discoveryType                          = DiscoveryType::kAll,
                          Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);

    /**
     * @brief
     *   Pair a CHIP device with the provided Rendezvous connection parameters.
     *   Use registered DevicePairingDelegate object to receive notifications on
     *   pairing status updates.
     *
     *   Note: Pairing process requires that the caller has registered PersistentStorageDelegate
     *         in the Init() call.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] rendezvousParams      The Rendezvous connection parameters
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams);

    /**
     * @overload
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] rendezvousParams      The Rendezvous connection parameters
     * @param[in] commissioningParams    The commissioning parameters (uses default if not supplied)
     */
    CHIP_ERROR PairDevice(NodeId remoteDeviceId, RendezvousParameters & rendezvousParams,
                          CommissioningParameters & commissioningParams);

    /**
     * @brief
     *   Start establishing a PASE connection with a node for the purposes of commissioning.
     *   Commissioners that wish to use the auto-commissioning functions should use the
     *   supplied "PairDevice" functions above to automatically establish a connection then
     *   perform commissioning. This function is intended to be use by commissioners that
     *   are not using the supplied auto-commissioner.
     *
     *   This function is non-blocking. PASE is established once the DevicePairingDelegate
     *   receives the OnPairingComplete call.
     *
     *   PASE connections can only be established with nodes that have their commissioning
     *   window open. The PASE connection will fail if this window is not open and the
     *   OnPairingComplete will be called with an error.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] params                The Rendezvous connection parameters
     */
    CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, RendezvousParameters & params);

    /**
     * @brief
     *   Start establishing a PASE connection with a node for the purposes of commissioning.
     *   Commissioners that wish to use the auto-commissioning functions should use the
     *   supplied "PairDevice" functions above to automatically establish a connection then
     *   perform commissioning. This function is intended to be used by commissioners that
     *   are not using the supplied auto-commissioner.
     *
     *   This function is non-blocking. PASE is established once the DevicePairingDelegate
     *   receives the OnPairingComplete call.
     *
     *   PASE connections can only be established with nodes that have their commissioning
     *   window open. The PASE connection will fail if this window is not open and in that case
     *   OnPairingComplete will be called with an error.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] setUpCode             The setup code for connecting to the device
     * @param[in] discoveryType         The network discovery type, defaults to DiscoveryType::kAll.
     * @param[in] resolutionData        Optional resolution data previously discovered on the network for the target device.
     */
    CHIP_ERROR EstablishPASEConnection(NodeId remoteDeviceId, const char * setUpCode,
                                       DiscoveryType discoveryType                          = DiscoveryType::kAll,
                                       Optional<Dnssd::CommonResolutionData> resolutionData = NullOptional);

    /**
     * @brief
     *   Start the auto-commissioning process on a node after establishing a PASE connection.
     *   This function is intended to be used in conjunction with the EstablishPASEConnection
     *   function. It can be called either before or after the DevicePairingDelegate receives
     *   the OnPairingComplete call. Commissioners that want to perform simple auto-commissioning
     *   should use the supplied "PairDevice" functions above, which will establish the PASE
     *   connection and commission automatically.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     * @param[in] params                The commissioning parameters
     */
    CHIP_ERROR Commission(NodeId remoteDeviceId, CommissioningParameters & params);
    CHIP_ERROR Commission(NodeId remoteDeviceId);

    /**
     * @brief
     *   This function instructs the commissioner to proceed to the next stage of commissioning after
     *   attestation is reported to an installed attestation delegate.
     *
     * @param[in] device                The device being commissioned.
     * @param[in] attestationResult     The attestation result to use instead of whatever the device
     *                                  attestation verifier came up with. May be a success or an error result.
     */
    CHIP_ERROR
    ContinueCommissioningAfterDeviceAttestation(DeviceProxy * device, Credentials::AttestationVerificationResult attestationResult);

    CHIP_ERROR GetDeviceBeingCommissioned(NodeId deviceId, CommissioneeDeviceProxy ** device);

    /**
     * @brief
     *   This function stops a pairing or commissioning process that is in progress.
     *   It does not delete the pairing of a previously paired device.
     *
     *   Note that cancelling an ongoing commissioning process is an asynchronous operation.
     *   The pairing delegate (if any) will receive OnCommissioningComplete and OnCommissioningFailure
     *   failure callbacks with a status code of CHIP_ERROR_CANCELLED once cancellation is complete.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     *
     * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR StopPairing(NodeId remoteDeviceId);

    /**
     * @brief
     *   Remove pairing for a paired device. If the device is currently being paired, it'll stop the pairing process.
     *
     * @param[in] remoteDeviceId        The remote device Id.
     *
     * @return CHIP_ERROR               CHIP_NO_ERROR on success, or corresponding error
     */
    CHIP_ERROR UnpairDevice(NodeId remoteDeviceId);

    //////////// SessionEstablishmentDelegate Implementation ///////////////
    void OnSessionEstablishmentError(CHIP_ERROR error) override;
    void OnSessionEstablished(const SessionHandle & session) override;

    void RendezvousCleanup(CHIP_ERROR status);

    void PerformCommissioningStep(DeviceProxy * device, CommissioningStage step, CommissioningParameters & params,
                                  CommissioningDelegate * delegate, EndpointId endpoint, Optional<System::Clock::Timeout> timeout);

    /**
     * @brief
     *   This function validates the Attestation Information sent by the device.
     *
     * @param[in] info Structure contatining all the required information for validating the device attestation.
     */
    CHIP_ERROR ValidateAttestationInfo(const Credentials::DeviceAttestationVerifier::AttestationInfo & info);

    /**
     * @brief
     * Sends CommissioningStepComplete report to the commissioning delegate. Function will fill in current step.
     * @params[in] err      error from the current step
     * @params[in] report   report to send. Current step will be filled in automatically
     */
    void
    CommissioningStageComplete(CHIP_ERROR err,
                               CommissioningDelegate::CommissioningReport report = CommissioningDelegate::CommissioningReport());

    /**
     * @brief
     *   This function is called by the DevicePairingDelegate to indicate that network credentials have been set
     * on the CommissioningParameters of the CommissioningDelegate using CommissioningDelegate.SetCommissioningParameters().
     * As a result, commissioning can advance to the next stage.
     *
     * The DevicePairingDelegate may call this method from the OnScanNetworksSuccess and OnScanNetworksFailure callbacks,
     * or it may call this method after obtaining network credentials using asyncronous methods (prompting user, cloud API call,
     * etc).
     *
     * If an error happens in the subsequent network commissioning step (either NetworkConfig or ConnectNetwork commands)
     * then the DevicePairingDelegate will receive the error in completionStatus.networkCommissioningStatus and the
     * commissioning stage will return to kNeedsNetworkCreds so that the DevicePairingDelegate can re-attempt with new
     * network information. The DevicePairingDelegate can exit the commissioning process by calling StopPairing.
     *
     * @return CHIP_ERROR   The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state (kNeedsNetworkCreds).
     */
    CHIP_ERROR NetworkCredentialsReady();

    /**
     * @brief
     *   This function is called by the DevicePairingDelegate to indicate that ICD registration info (ICDSymmetricKey,
     * ICDCheckInNodeId and ICDMonitoredSubject) have been set on the CommissioningParameters of the CommissioningDelegate
     * using CommissioningDelegate.SetCommissioningParameters(). As a result, commissioning can advance to the next stage.
     *
     * The DevicePairingDelegate may call this method from the OnICDRegistrationInfoRequired callback, or it may call this
     * method after obtaining required parameters for ICD registration using asyncronous methods (like RPC call etc).
     *
     * When the ICD Registration completes, OnICDRegistrationComplete will be called.
     *
     * @return CHIP_ERROR   The return status. Returns CHIP_ERROR_INCORRECT_STATE if not in the correct state
     * (kICDGetRegistrationInfo).
     */
    CHIP_ERROR ICDRegistrationInfoReady();

    /**
     * @brief
     *  This function returns the current CommissioningStage for this commissioner.
     */
    CommissioningStage GetCommissioningStage() { return mCommissioningStage; }

#if CONFIG_NETWORK_LAYER_BLE
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
    /**
     * @brief
     *   Prior to commissioning, the Controller should make sure the BleLayer transport
     *   is set to the Commissioner transport and not the Server transport.
     */
    void ConnectBleTransportToSelf();
#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE

    /**
     * @brief
     *   Once we have finished all commissioning work, the Controller should close the BLE
     *   connection to the device and establish CASE session / another PASE session to the device
     *   if needed.
     */
    void CloseBleConnection();
#endif
    /**
     * @brief
     *   Discover all devices advertising as commissionable.
     *   Should be called on main loop thread.
     * * @param[in] filter  Browse filter - controller will look for only the specified subtype.
     * @return CHIP_ERROR   The return status
     */
    CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter);

    /**
     * Stop commissionable discovery triggered by a previous
     * DiscoverCommissionableNodes call.
     */
    CHIP_ERROR StopCommissionableDiscovery();

    /**
     * @brief
     *   Returns information about discovered devices.
     *   Should be called on main loop thread.
     * @return const DiscoveredNodeData* info about the selected device. May be nullptr if no information has been returned yet.
     */
    const Dnssd::DiscoveredNodeData * GetDiscoveredDevice(int idx);

    /**
     * @brief
     *   Returns the max number of commissionable nodes this commissioner can track mdns information for.
     * @return int  The max number of commissionable nodes supported
     */
    int GetMaxCommissionableNodesSupported() { return kMaxCommissionableNodes; }

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    /**
     * @brief
     *   Called when a UDC message is received specifying the given instanceName
     * This method indicates that UDC Server needs the Commissionable Node corresponding to
     * the given instance name to be found. UDC Server will wait for OnCommissionableNodeFound.
     *
     * @param instanceName DNS-SD instance name for the client requesting commissioning
     *
     */
    void FindCommissionableNode(char * instanceName) override;

    /**
     * @brief
     *   Return the UDC Server instance
     *
     */
    UserDirectedCommissioningServer * GetUserDirectedCommissioningServer() { return mUdcServer; }
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

    /**
     * @brief
     *   Overrides method from AbstractDnssdDiscoveryController
     *
     * @param nodeData DNS-SD node information
     *
     */
    void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;

    void RegisterPairingDelegate(DevicePairingDelegate * pairingDelegate) { mPairingDelegate = pairingDelegate; }
    DevicePairingDelegate * GetPairingDelegate() const { return mPairingDelegate; }

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    // ClusterStateCache::Callback impl
    void OnDone(app::ReadClient *) override;
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    // Issue an NOC chain using the associated OperationalCredentialsDelegate. The NOC chain will
    // be provided in X509 DER format.
    // NOTE: This is only valid assuming that `mOperationalCredentialsDelegate` is what is desired
    // to issue the NOC chain.
    CHIP_ERROR IssueNOCChain(const ByteSpan & NOCSRElements, NodeId nodeId,
                             chip::Callback::Callback<OnNOCChainGeneration> * callback);

    void SetDeviceAttestationVerifier(Credentials::DeviceAttestationVerifier * deviceAttestationVerifier)
    {
        mDeviceAttestationVerifier = deviceAttestationVerifier;
    }

    Credentials::DeviceAttestationVerifier * GetDeviceAttestationVerifier() const { return mDeviceAttestationVerifier; }

    Optional<CommissioningParameters> GetCommissioningParameters()
    {
        return mDefaultCommissioner == nullptr ? NullOptional : MakeOptional(mDefaultCommissioner->GetCommissioningParameters());
    }

    // Reset the arm failsafe timer during commissioning.  If this returns
    // false, that means that the timer was already set for a longer time period
    // than the new time we are trying to set.  In this case, neither
    // onSuccess nor onFailure will be called.
    bool ExtendArmFailSafe(DeviceProxy * proxy, CommissioningStage step, uint16_t armFailSafeTimeout,
                           Optional<System::Clock::Timeout> commandTimeout, OnExtendFailsafeSuccess onSuccess,
                           OnExtendFailsafeFailure onFailure);

private:
    DevicePairingDelegate * mPairingDelegate = nullptr;

    DeviceProxy * mDeviceBeingCommissioned               = nullptr;
    CommissioneeDeviceProxy * mDeviceInPASEEstablishment = nullptr;

    CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
    bool mRunCommissioningAfterConnection  = false;
    Internal::InvokeCancelFn mInvokeCancelFn;

    ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
    UserDirectedCommissioningServer * mUdcServer = nullptr;
    // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
    UdcTransportMgr * mUdcTransportMgr = nullptr;
    uint16_t mUdcListenPort            = CHIP_UDC_PORT;
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY

#if CONFIG_NETWORK_LAYER_BLE
    static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
    static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
    RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle;
#endif

    CHIP_ERROR LoadKeyId(PersistentStorageDelegate * delegate, uint16_t & out);

    static void OnBasicFailure(void * context, CHIP_ERROR err);
    static void OnBasicSuccess(void * context, const chip::app::DataModel::NullObjectType &);

    /* This function sends a Device Attestation Certificate chain request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendCertificateChainRequestCommand(DeviceProxy * device, Credentials::CertificateType certificateType,
                                                  Optional<System::Clock::Timeout> timeout);
    /* This function sends an Attestation request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendAttestationRequestCommand(DeviceProxy * device, const ByteSpan & attestationNonce,
                                             Optional<System::Clock::Timeout> timeout);
    /* This function sends an CSR request to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendOperationalCertificateSigningRequestCommand(DeviceProxy * device, const ByteSpan & csrNonce,
                                                               Optional<System::Clock::Timeout> timeout);
    /* This function sends the operational credentials to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendOperationalCertificate(DeviceProxy * device, const ByteSpan & nocCertBuf, const Optional<ByteSpan> & icaCertBuf,
                                          IdentityProtectionKeySpan ipk, NodeId adminSubject,
                                          Optional<System::Clock::Timeout> timeout);
    /* This function sends the trusted root certificate to the device.
       The function does not hold a reference to the device object.
     */
    CHIP_ERROR SendTrustedRootCertificate(DeviceProxy * device, const ByteSpan & rcac, Optional<System::Clock::Timeout> timeout);

    /* This function is called by the commissioner code when the device completes
       the operational credential provisioning process.
       The function does not hold a reference to the device object.
       */
    CHIP_ERROR OnOperationalCredentialsProvisioningCompletion(DeviceProxy * device);

    /* Callback when the previously sent CSR request results in failure */
    static void OnCSRFailureResponse(void * context, CHIP_ERROR error);

    void ExtendArmFailSafeForDeviceAttestation(const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
                                               Credentials::AttestationVerificationResult result);
    static void OnCertificateChainFailureResponse(void * context, CHIP_ERROR error);
    static void OnCertificateChainResponse(
        void * context, const app::Clusters::OperationalCredentials::Commands::CertificateChainResponse::DecodableType & response);

    static void OnAttestationFailureResponse(void * context, CHIP_ERROR error);
    static void
    OnAttestationResponse(void * context,
                          const app::Clusters::OperationalCredentials::Commands::AttestationResponse::DecodableType & data);

    /**
     * @brief
     *   This function is called by the IM layer when the commissioner receives the CSR from the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] context               The context provided while registering the callback.
     * @param[in] data                  The response struct containing the following fields:
     *                                    NOCSRElements: CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     *                                    AttestationSignature: Cryptographic signature generated for the fields in the response
     * message.
     */
    static void OnOperationalCertificateSigningRequest(
        void * context, const app::Clusters::OperationalCredentials::Commands::CSRResponse::DecodableType & data);

    /* Callback when adding operational certs to device results in failure */
    static void OnAddNOCFailureResponse(void * context, CHIP_ERROR errro);
    /* Callback when the device confirms that it has added the operational certificates */
    static void
    OnOperationalCertificateAddResponse(void * context,
                                        const app::Clusters::OperationalCredentials::Commands::NOCResponse::DecodableType & data);

    /* Callback when the device confirms that it has added the root certificate */
    static void OnRootCertSuccessResponse(void * context, const chip::app::DataModel::NullObjectType &);
    /* Callback called when adding root cert to device results in failure */
    static void OnRootCertFailureResponse(void * context, CHIP_ERROR error);

    static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle);
    static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error);
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
    static void OnDeviceConnectionRetryFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error,
                                          System::Clock::Seconds16 retryTimeout);
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES

    static void OnDeviceAttestationInformationVerification(void * context,
                                                           const Credentials::DeviceAttestationVerifier::AttestationInfo & info,
                                                           Credentials::AttestationVerificationResult result);

    static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const ByteSpan & noc, const ByteSpan & icac,
                                           const ByteSpan & rcac, Optional<IdentityProtectionKeySpan> ipk,
                                           Optional<NodeId> adminSubject);
    static void OnArmFailSafe(void * context,
                              const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnSetRegulatoryConfigResponse(
        void * context,
        const chip::app::Clusters::GeneralCommissioning::Commands::SetRegulatoryConfigResponse::DecodableType & data);
    static void OnSetUTCError(void * context, CHIP_ERROR error);
    static void
    OnSetTimeZoneResponse(void * context,
                          const chip::app::Clusters::TimeSynchronization::Commands::SetTimeZoneResponse::DecodableType & data);

    static void
    OnScanNetworksResponse(void * context,
                           const app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & data);
    static void OnScanNetworksFailure(void * context, CHIP_ERROR err);
    static void
    OnNetworkConfigResponse(void * context,
                            const app::Clusters::NetworkCommissioning::Commands::NetworkConfigResponse::DecodableType & data);
    static void OnConnectNetworkResponse(
        void * context, const chip::app::Clusters::NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data);
    static void OnCommissioningCompleteResponse(
        void * context,
        const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & data);
    static void OnDisarmFailsafe(void * context,
                                 const app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnDisarmFailsafeFailure(void * context, CHIP_ERROR error);
    void DisarmDone();
    static void OnArmFailSafeExtendedForDeviceAttestation(
        void * context, const chip::app::Clusters::GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data);
    static void OnFailedToExtendedArmFailSafeDeviceAttestation(void * context, CHIP_ERROR error);

    static void OnICDManagementRegisterClientResponse(
        void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data);

    /**
     * @brief
     *   This function processes the CSR sent by the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] proxy           device proxy
     * @param[in] NOCSRElements   CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     * @param[in] AttestationSignature       Cryptographic signature generated for all the above fields.
     * @param[in] dac               device attestation certificate
     * @param[in] pai               Product Attestation Intermediate certificate
     * @param[in] csrNonce          certificate signing request nonce
     */
    CHIP_ERROR ProcessCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
                          const ByteSpan & dac, const ByteSpan & pai, const ByteSpan & csrNonce);

    /**
     * @brief
     *   This function validates the CSR information from the device.
     *   (Reference: Specifications section 11.18.5.6. NOCSR Elements)
     *
     * @param[in] proxy           device proxy
     * @param[in] NOCSRElements   CSR elements as per specifications section 11.22.5.6. NOCSR Elements.
     * @param[in] AttestationSignature       Cryptographic signature generated for all the above fields.
     * @param[in] dac               device attestation certificate
     * @param[in] csrNonce          certificate signing request nonce
     */
    CHIP_ERROR ValidateCSR(DeviceProxy * proxy, const ByteSpan & NOCSRElements, const ByteSpan & AttestationSignature,
                           const ByteSpan & dac, const ByteSpan & csrNonce);

    /**
     * @brief
     *   This function processes the DAC or PAI certificate sent by the device.
     */
    CHIP_ERROR ProcessCertificateChain(const ByteSpan & certificate);

    void HandleAttestationResult(CHIP_ERROR err);

    CommissioneeDeviceProxy * FindCommissioneeDevice(NodeId id);
    CommissioneeDeviceProxy * FindCommissioneeDevice(const Transport::PeerAddress & peerAddress);
    void ReleaseCommissioneeDevice(CommissioneeDeviceProxy * device);

    template <typename RequestObjectT>
    CHIP_ERROR SendCommissioningCommand(DeviceProxy * device, const RequestObjectT & request,
                                        CommandResponseSuccessCallback<typename RequestObjectT::ResponseType> successCb,
                                        CommandResponseFailureCallback failureCb, EndpointId endpoint,
                                        Optional<System::Clock::Timeout> timeout);
    void SendCommissioningReadRequest(DeviceProxy * proxy, Optional<System::Clock::Timeout> timeout,
                                      app::AttributePathParams * readPaths, size_t readPathsSize);
    void CancelCommissioningInteractions();

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    void ParseCommissioningInfo();
    // Parsing attributes read in kReadCommissioningInfo stage.
    CHIP_ERROR ParseCommissioningInfo1(ReadCommissioningInfo & info);
    // Parsing attributes read in kReadCommissioningInfo2 stage.
    CHIP_ERROR ParseCommissioningInfo2(ReadCommissioningInfo & info);
    // Called by ParseCommissioningInfo2
    CHIP_ERROR ParseFabrics(ReadCommissioningInfo & info);
    CHIP_ERROR ParseICDInfo(ReadCommissioningInfo & info);
    // Called by ParseCommissioningInfo
    void ParseTimeSyncInfo(ReadCommissioningInfo & info);
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    static CHIP_ERROR
    ConvertFromOperationalCertStatus(chip::app::Clusters::OperationalCredentials::NodeOperationalCertStatusEnum err);

    // Sends commissioning complete callbacks to the delegate depending on the status. Sends
    // OnCommissioningComplete and either OnCommissioningSuccess or OnCommissioningFailure depending on the given completion status.
    void SendCommissioningCompleteCallbacks(NodeId nodeId, const CompletionStatus & completionStatus);

    // Cleans up and resets failsafe as appropriate depending on the error and the failed stage.
    // For success, sends completion report with the CommissioningDelegate and sends callbacks to the PairingDelegate
    // For failures after AddNOC succeeds, sends completion report with the CommissioningDelegate and sends callbacks to the
    // PairingDelegate. In this case, it does not disarm the failsafe or close the pase connection. For failures up through AddNOC,
    // sends a command to immediately expire the failsafe, then sends completion report with the CommissioningDelegate and callbacks
    // to the PairingDelegate upon arm failsafe command completion.
    void CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus);

    // Extend the fail-safe before trying to do network-enable (since after that
    // point, for non-concurrent-commissioning devices, we may not have a way to
    // extend it).
    void ExtendFailsafeBeforeNetworkEnable(DeviceProxy * device, CommissioningParameters & params, CommissioningStage step);

    chip::Callback::Callback<OnDeviceConnected> mOnDeviceConnectedCallback;
    chip::Callback::Callback<OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
    chip::Callback::Callback<OnDeviceConnectionRetry> mOnDeviceConnectionRetryCallback;
#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES

    chip::Callback::Callback<Credentials::DeviceAttestationVerifier::OnAttestationInformationVerification>
        mDeviceAttestationInformationVerificationCallback;

    chip::Callback::Callback<OnNOCChainGeneration> mDeviceNOCChainCallback;
    SetUpCodePairer mSetUpCodePairer;
    AutoCommissioner mAutoCommissioner;
    CommissioningDelegate * mDefaultCommissioner =
        nullptr; // Commissioning delegate to call when PairDevice / Commission functions are used
    CommissioningDelegate * mCommissioningDelegate =
        nullptr; // Commissioning delegate that issued the PerformCommissioningStep command
    CompletionStatus mCommissioningCompletionStatus;

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    Platform::UniquePtr<app::ClusterStateCache> mAttributeCache;
    Platform::UniquePtr<app::ReadClient> mReadClient;
#endif
    Credentials::AttestationVerificationResult mAttestationResult;
    Platform::UniquePtr<Credentials::DeviceAttestationVerifier::AttestationDeviceInfo> mAttestationDeviceInfo;
    Credentials::DeviceAttestationVerifier * mDeviceAttestationVerifier = nullptr;
};

} // namespace Controller
} // namespace chip
