using System.Net.Sockets;

namespace Flo.Installer.Provisioning;

internal static class HealthCheck
{
    public static async Task WaitForPortAsync(
        string host,
        int port,
        TimeSpan timeout,
        string description,
        CancellationToken ct)
    {
        var deadline = DateTime.UtcNow + timeout;
        Exception? last = null;
        while (DateTime.UtcNow < deadline)
        {
            ct.ThrowIfCancellationRequested();
            try
            {
                using var client = new TcpClient();
                await client.ConnectAsync(host, port, ct);
                return;
            }
            catch (SocketException ex)
            {
                last = ex;
                await Task.Delay(500, ct);
            }
        }
        throw new TimeoutException(
            $"{description} at {host}:{port} did not become healthy within {timeout.TotalSeconds:0}s. Last error: {last?.Message}");
    }
}
