/*
 *
 *    Copyright (c) 2020-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
 *    This file contains definitions for DeviceProxy for a device that's undergoing
 *    commissioning process. The objects of this will be used by Controller applications
 *    to interact with the device. The class provides mechanism to construct, send and receive
 *    messages to and from the corresponding CHIP devices.
 */

#pragma once

#include <app/CommandSender.h>
#include <app/DeviceProxy.h>
#include <app/util/basic-types.h>
#include <controller/CHIPDeviceControllerSystemState.h>
#include <controller/OperationalCredentialsDelegate.h>
#include <lib/core/CHIPCallback.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/DLLUtil.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/secure_channel/PASESession.h>
#include <transport/SessionHolder.h>
#include <transport/SessionManager.h>
#include <transport/TransportMgr.h>
#include <transport/raw/MessageHeader.h>
#include <transport/raw/UDP.h>

namespace chip {

constexpr size_t kAttestationNonceLength = 32;

struct ControllerDeviceInitParams
{
    SessionManager * sessionManager          = nullptr;
    Messaging::ExchangeManager * exchangeMgr = nullptr;
};

class CommissioneeDeviceProxy : public DeviceProxy, public SessionDelegate
{
public:
    ~CommissioneeDeviceProxy() override;
    CommissioneeDeviceProxy() : mSecureSession(*this) {}
    CommissioneeDeviceProxy(const CommissioneeDeviceProxy &) = delete;

    /**
     * @brief
     *   Send the command in internal command sender.
     */
    CHIP_ERROR SendCommands(app::CommandSender * commandObj, Optional<System::Clock::Timeout> timeout) override;

    /**
     * @brief
     *   Initialize a new device object with secure session manager, inet layer object,
     *   and other device specific parameters. This variant of function is typically used when
     *   a new device is paired, and the corresponding device object needs to updated with
     *   all device specifc parameters (address, port, interface etc).
     *
     *   This is not done as part of constructor so that the controller can have a list of
     *   uninitialized/unpaired device objects. The object is initialized only when the device
     *   is actually paired.
     *
     * @param[in] params       Wrapper object for transport manager etc.
     * @param[in] deviceId     Node ID of the device
     * @param[in] peerAddress  The location of the peer. MUST be of type Transport::Type::kUdp
     */
    void Init(ControllerDeviceInitParams params, NodeId deviceId, const Transport::PeerAddress & peerAddress)
    {
        mSessionManager = params.sessionManager;
        mExchangeMgr    = params.exchangeMgr;
        mPeerId         = PeerId().SetNodeId(deviceId);
        mState          = ConnectionState::Connecting;

        mDeviceAddress = peerAddress;
    }

    /**
     * @brief
     *   Called when the associated session is released
     *
     *   The receiver should release all resources associated with the connection.
     */
    void OnSessionReleased() override;

    /**
     *  In case there exists an open session to the device, mark it as expired.
     */
    void CloseSession();

    void Disconnect() override { CloseSession(); }

    /**
     * @brief
     *   Update data of the device.
     *
     *   This function will set new IP address, port and MRP retransmission intervals of the device.
     *
     * @param[in] addr   Address of the device to be set.
     * @param[in] config MRP parameters
     *
     * @return CHIP_NO_ERROR if the data has been updated, an error code otherwise.
     */
    CHIP_ERROR UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config);

    /**
     * @brief
     * Called to indicate this proxy has been paired successfully.
     *
     * This stores the session details in the session manager.
     */
    CHIP_ERROR SetConnected(const SessionHandle & session);

    bool IsSecureConnected() const override { return mState == ConnectionState::SecureConnected; }

    bool IsSessionSetupInProgress() const { return mState == ConnectionState::Connecting; }

    NodeId GetDeviceId() const override { return mPeerId.GetNodeId(); }
    void ShutdownSubscriptions() override {}
    PeerId GetPeerId() const { return mPeerId; }
    CHIP_ERROR SetPeerId(ByteSpan rcac, ByteSpan noc) override;
    const Transport::PeerAddress & GetPeerAddress() const { return mDeviceAddress; }

    chip::Optional<SessionHandle> GetSecureSession() const override { return mSecureSession.Get(); }

    Messaging::ExchangeManager * GetExchangeManager() const override { return mExchangeMgr; }

    PASESession & GetPairing() { return mPairing; }

    Transport::Type GetDeviceTransportType() const { return mDeviceAddress.GetTransportType(); }

private:
    enum class ConnectionState
    {
        NotConnected,
        Connecting,
        SecureConnected,
    };

    /* Compressed fabric ID and node ID assigned to the device. */
    PeerId mPeerId;

    /** Address used to communicate with the device.
     */
    Transport::PeerAddress mDeviceAddress = Transport::PeerAddress::UDP(Inet::IPAddress::Any);

    ConnectionState mState = ConnectionState::NotConnected;

    PASESession mPairing;

    SessionManager * mSessionManager = nullptr;

    Messaging::ExchangeManager * mExchangeMgr = nullptr;

    SessionHolderWithDelegate mSecureSession;
};

} // namespace chip
