/*
 * 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_SSAP_CLIENT_H
#define SLE_SSAP_CLIENT_H

#include <iostream>
#include <memory>
#include "sle_ssap_client_config.h"
#include "sle_common_config.h"
#include "sle_error_code.h"

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

    /**
     *   @brief   Find service callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] result - service information
     *   @param   [in] errCode - find service result error code
     *   @return  None
     */
    virtual void OnFindService(uint16_t connectId, const ClientFindServiceRes &result, SleErrorCode errCode) = 0;

    /**
     *   @brief   Find property callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] result - property information
     *   @param   [in] errCode - find property result error code
     *   @return  None
     */
    virtual void OnFindProperty(uint16_t connectId, const ClientFindPropertyRes &result, SleErrorCode errCode) = 0;

    /**
     *   @brief   Find completed callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] result - input find parameter
     *   @param   [in] errCode - find completed result error code
     *   @return  None
     */
    virtual void OnFindComplete(uint16_t connectId, const ClientFindStructureRes &result, SleErrorCode errCode) = 0;

    /**
     *   @brief   Receive write response callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] result - write result info
     *   @param   [in] errCode - write result error code
     *   @return  None
     */
    virtual void OnWriteResult(uint16_t connectId, const ClientWriteRes &result, SleErrorCode errCode) = 0;

    /**
     *   @brief   Receive read response callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] value - read data
     *   @param   [in] errCode - read result error code
     *   @return  None
     */
    virtual void OnReadResult(uint16_t connectId, const ClientHandleValue &value, SleErrorCode errCode) = 0;

    /**
     *   @brief   Read by uuid completed callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] result - read data
     *   @param   [in] errCode - read result error code
     *   @return  None
     */
    virtual void OnReadByUuidComplete(uint16_t connectId, const ClientReadByUuidCmpRes &result, SleErrorCode errCode) = 0;

    /**
     *   @brief   Exchange info callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] info - exchange info
     *   @param   [in] errCode - exchange info result error code
     *   @return  None
     */
    virtual void OnExchangeInfo(uint16_t connectId, const SsapMtuInfo &info, SleErrorCode errCode) = 0;

    /**
     *   @brief   Receiving a notification callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] value - notification data
     *   @param   [in] errCode - error code
     *   @return  None
     */
    virtual void OnNotification(uint16_t connectId, const ClientHandleValue &value, SleErrorCode errCode) = 0;

    /**
     *   @brief   Receiving a indication callback
     *
     *   @param   [in] connectId - connnection id
     *   @param   [in] value - indication data
     *   @param   [in] errCode - error code
     *   @return  None
     */
    virtual void OnIndication(uint16_t connectId, const ClientHandleValue &value, SleErrorCode errCode) = 0;
};

class SleSsapClient {
public:
    /**
     *   @brief   A constructor used to create a <b>SleSsapClient</b> instance.
     *
     *   @param   [in] uuid - server application uuid
     */
    explicit SleSsapClient(const SleUuid &uuid);

    /**
     *   @brief   A constructor used to create a <b>SleSsapClient</b> instance.
     */
    SleSsapClient() = delete;

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

    /**
     *   @brief   Find structure async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - structure parameter
     *   @return  SleErrorCode
     *
     *   @note structure uuid, if NULL, discover all structure, else filter by uuid.
     *   @note Receive callback info in OnFindService and OnFindComplete.
     */
    SleErrorCode FindSsapStructure(uint16_t connectId, const ClientFindStructure &param);

    /**
     *   @brief   Find structure async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - read request parameter
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnReadResult and OnReadByUuidComplete.
     */
    SleErrorCode ReadRequestByUuid(uint16_t connectId, const ClientReadReqByUUID &param);

    /**
     *   @brief   Find structure async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] handle - handle
     *   @param   [in] type - ssap property type
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnReadResult.
     */
    SleErrorCode ReadRequest(uint16_t connectId, uint16_t handle, SleSsapPropertyType type);

    /**
     *   @brief   Find structure async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - write request parameter
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnWriteResult.
     */
    SleErrorCode WriteRequest(uint16_t connectId, const ClientWriteParam &param);

    /**
     *   @brief   Find structure sync
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] param - write request parameter
     *   @return  SleErrorCode
     */
    SleErrorCode WriteCommand(uint16_t connectId, const ClientWriteParam &param);

    /**
     *   @brief   Find structure async
     *
     *   @param   [in] connectId - connection id
     *   @param   [in] info - mtu info
     *   @return  SleErrorCode
     *
     *   @note Receive callback info in OnExchangeInfo.
     */
    SleErrorCode ExchangeInfo(uint16_t connectId, const SsapMtuInfo &info);

    /**
     *   @brief   Register ssap client callback sync
     *
     *   @param   [in] callback - callback
     *   @return  SleErrorCode
     */
    SleErrorCode RegisterClientCallback(std::shared_ptr<SleSsapClientCallback> callback);

    /**
     *   @brief   Unregister ssap client callback sync
     *
     *   @param   [in] callback - callback
     *   @return  SleErrorCode
     */
    SleErrorCode UnregisterClientCallback(std::shared_ptr<SleSsapClientCallback> callback);

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

#endif // SLE_SSAP_CLIENT_H