/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * 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.
 */

#ifndef SLE_CONNECT_H
#define SLE_CONNECT_H

#include <iostream>
#include <memory>
#include <vector>
#include "sle_connect_config.h"
#include "sle_device_config.h"
#include "sle_common_config.h"
#include "sle_error_code.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
class SleConnectManagerCallback {
public:
    /**
     *   @brief A destructor used to delete the <b>SleConnectManagerCallback</b> instance.
     */
    virtual ~SleConnectManagerCallback() = default;

    /**
     *   @brief   Connection state change callback
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] address - remote device address
     *   @param   [in] connState - connection state
     *   @param   [in] pairState - pair state
     *   @param   [in] reason - connection reason
     *   @return  None
     */
    virtual void OnConnectStateChange(uint16_t connectId, const SleDeviceAddress &address, SleConnectState connState,
        SlePairState pairState, SleDisConnectReason reason) = 0;

    /**
     *   @brief   Connection param update callback
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - update param
     *   @param   [in] errCode - connection param update result error code
     *   @return  None
     */
    virtual void OnConnectParamUpdateComplete(uint16_t connectId, const SleConnectionParamUpdateEvt &param, SleErrorCode errCode) = 0;

    /**
     *   @brief   Authentication complete callback
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] address - remote device address
     *   @param   [in] info - authentication result
     *   @param   [in] errCode - authentication result error code
     *   @return  None
     */
    virtual void OnAuthComplete(uint16_t connectId, const SleDeviceAddress &address, const SleAuthInfo &info, SleErrorCode errCode) = 0;

    /**
     *   @brief   Pairing complete callback
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] address - remote device address
     *   @param   [in] errCode - pairing result error code
     *   @return  None
     */
    virtual void OnPairComplete(uint16_t connectId, const SleDeviceAddress &address, SleErrorCode errCode) = 0;
};

// todo 定义类做参数校验及日志记录, 实现类impl做具体实现, 成员函数命名保持一致
class SleConnectManager {
public:
    /**
     *   @brief A constructor used to create a <b>SleConnectManager</b> instance.
     */
    SleConnectManager();

    /**
     *   @brief A constructor used to delete a <b>SleConnectManager</b> instance.
     */
    ~SleConnectManager();

    /**
     *   @brief   Send connect request to remote device async
     *
     *   @param   [in] address - remote device address
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectStateChange
     */
    SleErrorCode Connect(const SleDeviceAddress &address);

    /**
     *   @brief   Send disconnect request to remote device async
     *
     *   @param   [in] address - remote device address
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectStateChange
     */
    SleErrorCode Disconnect(const SleDeviceAddress &address);

    /**
     *   @brief   Get connection id of remote device sync
     *
     *   @param   [in] address - remote device address
     *   @param   [out] connectId - connection id of remote device
     *   @return  SleErrorCode
     */
    SleErrorCode GetConnectId(const SleDeviceAddress &address, uint16_t &connectId);

    /**
     *   @brief   Get connection state
     *
     *   @param   [in] address - remote device address
     *   @param   [out] state - connection id of remote device
     *   @return  SleErrorCode
     */
    SleErrorCode GetConnectState(const SleDeviceAddress &address, SleConnectState &state);

    /**
     *   @brief   Get the list of connected devices sync
     *
     *   @param   [out] devList - devices list
     *   @param   [out] number - connected devices number
     *   @return  SleErrorCode
     */
    SleErrorCode GetConnectDeviceList(std::vector<SleConnectDev> &devices, uint16_t &number);

    /**
     *   @brief   Send connection parameter update request to remote device async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - connection param
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectParamUpdateComplete
     */
    SleErrorCode UpdateConnectParam(uint16_t connectId, const SleConnectParam &param);

    /**
     *   @brief   Update the parameters of the ALL SLE connection.
     *
     *   @param   [out] connectDevList Indicates the ID list of the connected devices.
     *   @param   [out] success update dev num.
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectParamUpdateComplete
     */
    SleErrorCode UpdateAllConnectParam(std::vector<SleConnectDev> &successUpdateDevList, uint16_t &number);

    /**
     * @brief   Get recommend send data size by connect id
     *
     * @param   [in] connect Id.
     * @param   [out] recommend send data size.
     * @return  Returns the operation result status @link SleErrorCode
     *
     */
    SleErrorCode GetRecomSendDataSize(uint16_t connectId, uint32_t &recomSendDataSize);

    /**
     *   @brief   Send pairing request to remote device async
     *
     *   @param   [in] address - remote device address
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnAuthComplete and OnPairComplete
     */
    SleErrorCode SendPairRequest(const SleDeviceAddress &address);

    /**
     *   @brief   Remove paired device async
     *
     *   @param   [in] address - remote device address
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectStateChange
     */
    SleErrorCode RemovePairedDevice(const SleDeviceAddress &address);

    /**
     *   @brief   Remove all pairing async
     *
     *   @param   [in] address - remote device address
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnConnectStateChange
     */
    SleErrorCode RemoveAllPairedDevices();

    /**
     *   @brief   Get paired device number sync
     *
     *   @param   [out] number - device number
     *   @return  SleErrorCode
     */
    SleErrorCode GetPairedDevicesNum(uint16_t &number);

    /**
     *   @brief   Get paired device sync
     *
     *   @param   [out] devices - paired device address
     *   @param   [out] number - device number
     *   @return  SleErrorCode
     */
    SleErrorCode GetPairedDevices(std::vector<SleDeviceAddress> &devices, uint16_t &number);

    /**
     *   @brief   Get pair state sync
     *
     *   @param   [in] address - device address
     *   @param   [out] state - pair state
     *   @return  SleErrorCode
     */
    SleErrorCode GetPairState(const SleDeviceAddress &address, SlePairState &state);

    /**
     *   @brief   Read remote device rssi value sync
     *
     *   @param   [in] connectId - connection id
     *   @param   [out] rssi - rssi
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnReadRssiComplete. Not supported now
     */
    SleErrorCode ReadRemoteRssi(uint16_t connectId, int8_t &rssi);

    /**
     *   @brief   Register connection callbacks sync
     *
     *   @param   [in] callback - callback function
     *   @return  SleErrorCode
     */
    SleErrorCode RegisterConnectCallback(std::shared_ptr<SleConnectManagerCallback> callback);

    /**
     *   @brief   Unregister connection callbacks sync
     *
     *   @param   [in] callback - callback function
     *   @return  SleErrorCode
     */
    SleErrorCode UnregisterConnectCallback(std::shared_ptr<SleConnectManagerCallback> callback);

private:
    class SleConnectManagerImpl;
    std::unique_ptr<SleConnectManagerImpl> pimpl_;
    SLE_DISALLOW_COPY_AND_ASSIGN(SleConnectManager);
};
} // SleStandard
} // NearLink
} // OHOS

#endif // SLE_CONNECT_H