//using System;
using System.Text;
using SafeMobileLib.WebsocketClient.Models;
using System.Net.WebSockets;
using System.Threading.Tasks;
using System;
namespace SafeMobileLib.WebsocketClient
{
///
/// A simple websocket client with built-in reconnection and error handling
///
public interface IWebsocketClient : IDisposable
{
///
/// Get or set target websocket url
///
Uri Url { get; set; }
///
/// Stream with received message (raw format)
///
IObservable MessageReceived { get; }
///
/// Stream for reconnection event (triggered after the new connection)
///
IObservable ReconnectionHappened { get; }
///
/// Stream for disconnection event (triggered after the connection was lost)
///
IObservable DisconnectionHappened { get; }
///
/// Time range in ms, how long to wait before reconnecting if no message comes from server.
/// Set null to disable this feature.
/// Default: 1 minute.
///
TimeSpan? ReconnectTimeout { get; set; }
///
/// Time range in ms, how long to wait before reconnecting if last reconnection failed.
/// Set null to disable this feature.
/// Default: 1 minute.
///
TimeSpan? ErrorReconnectTimeout { get; set; }
///
/// Get or set the name of the current websocket client instance.
/// For logging purpose (in case you use more parallel websocket clients and want to distinguish between them)
///
string Name { get; set; }
///
/// Returns true if Start() method was called at least once. False if not started or disposed
///
bool IsStarted { get; }
///
/// Returns true if client is running and connected to the server
///
bool IsRunning { get; }
///
/// Enable or disable reconnection functionality (enabled by default)
///
bool IsReconnectionEnabled { get; set; }
///
/// Returns currently used native websocket client.
/// Use with caution, on every reconnection there will be a new instance.
///
ClientWebSocket NativeClient { get; }
///
/// Sets used encoding for sending and receiving text messages.
/// Default is UTF8
///
Encoding MessageEncoding { get; set; }
///
/// Start listening to the websocket stream on the background thread.
/// In case of connection error it doesn't throw an exception.
/// Only streams a message via 'DisconnectionHappened' and logs it.
///
Task Start();
///
/// Start listening to the websocket stream on the background thread.
/// In case of connection error it throws an exception.
/// Fail fast approach.
///
Task StartOrFail();
///
/// Stop/close websocket connection with custom close code.
/// Method doesn't throw exception, only logs it and mark client as closed.
///
/// Returns true if close was initiated successfully
Task Stop(WebSocketCloseStatus status, string statusDescription);
///
/// Stop/close websocket connection with custom close code.
/// Method could throw exceptions, but client is marked as closed anyway.
///
/// Returns true if close was initiated successfully
Task StopOrFail(WebSocketCloseStatus status, string statusDescription);
///
/// Send message to the websocket channel.
/// It inserts the message to the queue and actual sending is done on an other thread
///
/// Message to be sent
void Send(string message);
///
/// Send binary message to the websocket channel.
/// It inserts the message to the queue and actual sending is done on an other thread
///
/// Binary message to be sent
void Send(byte[] message);
///
/// Send message to the websocket channel.
/// It doesn't use a sending queue,
/// beware of issue while sending two messages in the exact same time
/// on the full .NET Framework platform
///
/// Message to be sent
Task SendInstant(string message);
///
/// Send binary message to the websocket channel.
/// It doesn't use a sending queue,
/// beware of issue while sending two messages in the exact same time
/// on the full .NET Framework platform
///
/// Message to be sent
Task SendInstant(byte[] message);
///
/// Force reconnection.
/// Closes current websocket stream and perform a new connection to the server.
/// In case of connection error it doesn't throw an exception, but tries to reconnect indefinitely.
///
Task Reconnect();
///
/// Force reconnection.
/// Closes current websocket stream and perform a new connection to the server.
/// In case of connection error it throws an exception and doesn't perform any other reconnection try.
///
Task ReconnectOrFail();
///
/// Stream/publish fake message (via 'MessageReceived' observable).
/// Use for testing purposes to simulate a server message.
///
/// Message to be stream
void StreamFakeMessage(ResponseMessage message);
}
}