#pragma once

#include <balancer/kernel/net/sockops.h>

#include <util/generic/flags.h>

namespace NSrvKernel {

    enum class ETcpListen : ui32 {
        NonBlocking = 1,
        ReuseAddr = 2,
        ReusePort = 4,
        Default = NonBlocking | ReusePort
    };

    Y_DECLARE_FLAGS(ETcpListenFlags, ETcpListen);
    Y_DECLARE_OPERATORS_FOR_FLAGS(ETcpListenFlags);

    enum class ETcpConn : ui32 {
        NonBlocking = 1,
        NoDelay = 2,
        Keepalive = 4,
        Default = NonBlocking | NoDelay | Keepalive
    };

    Y_DECLARE_FLAGS(ETcpConnFlags, ETcpConn);
    Y_DECLARE_OPERATORS_FOR_FLAGS(ETcpConnFlags);

    TErrorOr<TSocketHolder> ListenTcp(
        const TSockAddr& addr, unsigned backlog, ETcpListenFlags = ETcpListen::Default) noexcept;

    TErrorOr<TSocketHolder> ConnectTcp(const TSockAddr&,
                                       ETcpConnFlags = ETcpConn::Default, TSockBufSize = {}, TTcpKeepalive = {}) noexcept;

    TErrorOr<TAcceptResult> AcceptTcp(
        SOCKET sock, ETcpConnFlags = ETcpConn::Default, TSockBufSize = {}, TTcpKeepalive = {}) noexcept;

    TErrorOr<size_t> Write(SOCKET sock, TStringBuf data) noexcept;
}
