// Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto.  Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once

#include <cstdint>

namespace carb
{
namespace messaging
{
struct Channel;

/**
 * Defines type on message.
 */
enum class Type
{
    eError,
    eMessage,
    eHello,
    eJoin,
    eLeft,
    eDeleted,
};

/**
 * Response results for messaging.
 */
enum class Status
{
    eOk,
    eErrorUnknown
};

/**
 * Callback return type.
 */
enum class CallbackReturnType : uint64_t
{
    eContinue = 0, ///! Continue callback subscription.
    eStop = 1 ///! Stop callback subscription.
};

/**
 * Description of Listen channel parameters.
 */
struct ListenChannelDesc
{
    void* connection; ///! Native connection handle for message channel.
    const char* path; ///! Path of message channel to listen to.
};

/**
 * Defines a message body.
 */
struct MessageResult
{
    carb::messaging::Status status; ///! Status of the message
    const char* statusDescription; ///! Status in a more descriptive string.
    Channel* channel; ///! Channel where the message is received from.
    const char* from; ///! The sender id of this message.
    const uint8_t* ptr; ///! Payload of the message.
    uint64_t size; ///! Size of the payload.
    Type type; ///! Type of message.
};

/**
 * Description of message to be sent.
 */
struct SendMessageDesc
{
    Channel* channel; ///! Channel to send this message to.
    const char* to; ///! Recipient of the message. use nullptr to broadcast.
    const uint8_t* ptr; ///! Payload of the message. A copy will be made internally.
    uint64_t size; ///! Size of the message.
    bool waitForAnswer; ///! Whether to wait for answer or not.
};

/**
 * Callback function when a message is sent or received.
 *
 * @param result The message body.
 * @param userPtr The custom user data to be passed into callback function.
 * @return if to continue or stop callback subscription.
 */
typedef CallbackReturnType (*OnMessageFn)(const MessageResult* result, void* userPtr);

}
}
