using System.Net.Sockets;

namespace InnovEnergy.Lib.Channels.V2.Connections;

public class TcpClientConnection : Connection<Socket>
{
    private String Hostname  { get; }
    private UInt16 Port      { get; }
    private Byte[] Buffer    { get; }
    private Int32  TimeoutMs { get; }

    private static readonly LingerOption LingerState = new LingerOption(false, 0);

    public TcpClientConnection(String hostname, 
                               UInt16 port, 
                             TimeSpan timeout,
                               UInt32 bufferSize = 8192)
    {
        Hostname  = hostname;
        Port      = port;
        Buffer    = new Byte[bufferSize];
        TimeoutMs = (Int32)timeout.TotalMilliseconds;
    }

    public override async Task<Socket> Open()
    {
        var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
        {
            Blocking          = true,
            NoDelay           = true,
            LingerState       = LingerState,
            ReceiveBufferSize = Buffer.Length,
            SendBufferSize    = Buffer.Length,
            ReceiveTimeout    = TimeoutMs,
            SendTimeout       = TimeoutMs,
        };

        var cts = new CancellationTokenSource();
        cts.CancelAfter(TimeoutMs);

        await socket.ConnectAsync(Hostname, Port, cts.Token);

        return socket;
    }
}