using System.Net;
using System.Net.Sockets;

namespace eSuite.API.HealthChecks;

/// <summary>
/// Class to provide and interface facade for the Socket class
/// </summary>
public class SocketFacade : ISocketFacade
{
    private Socket _socket;

    /// <summary>
    /// Creates a new Socket using the parameters provided.
    /// </summary>
    /// <param name="endPointAddressFamily"></param>
    /// <param name="stream"></param>
    /// <param name="tcp"></param>
    public SocketFacade(AddressFamily endPointAddressFamily, SocketType stream, ProtocolType tcp)
    {
        _socket = new Socket(endPointAddressFamily, stream, tcp);
    }


    /// <summary>
    /// Disposes of the underlying socket.
    /// </summary>
    public void Dispose()
    {
        // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
        if (_socket == null)
            return;

        GC.SuppressFinalize(this);
        _socket.Dispose();
        _socket = null!;
    }

    /// <summary>
    /// Connect to the socket
    /// </summary>
    /// <param name="endPoint"></param>
    public void Connect(IPEndPoint endPoint)
    {
        _socket.Connect(endPoint);
    }

    /// <summary>
    /// Sends data to the socket
    /// </summary>
    /// <param name="dataArray"></param>
    /// <param name="offset"></param>
    /// <param name="size"></param>
    /// <param name="socketFlags"></param>
    public void Send(byte[] dataArray, int offset, int size, SocketFlags socketFlags)
    {
        _socket.Send(dataArray, offset, size, socketFlags);
    }

    /// <summary>
    /// Receives data from the socket
    /// </summary>
    /// <param name="responseArray"></param>
    /// <param name="offset"></param>
    /// <param name="size"></param>
    /// <param name="socketFlags"></param>
    /// <returns></returns>
    public int Receive(byte[] responseArray, int offset, int size, SocketFlags socketFlags)
    {
        return _socket.Receive(responseArray, offset, size, socketFlags);
    }

    /// <summary>
    /// Number of bytes available for reading.
    /// </summary>
    public int Available => _socket.Available;
}