
--------------------------------------------------------------------------------
-- LuaSocket module
--------------------------------------------------------------------------------

---@alias socket_timeout number|nil

---@class socket_tcp_client*
local socket_tcp_client = {}

---@class socket_udp_client*
local socket_udp_client = {}

---@class socket_server*: socket_tcp_client*
local socket_server = {}

---@class socket_dns*
local socket_dns = {}

---@type socket_core*
local core = require("socket.core")

---@class socket*: socket_core*
---@field _VERSION string version
---@field BLOCKSIZE integer LTN12 block size
---@field dns socket_core_dns* DNS Tools
---@field sourcet table source Factory table
---@field sinkt table sink Factory table
---@type socket*
local M = core

M.dns = socket_dns
M.BLOCKSIZE = 2048

--- Create TCP socket
---@return socket_tcp_client* client TCP socket
function M.tcp() end

--- Create IPv4 TCP socket
---@return socket_tcp_client* client TCP socket
function M.tcp4() end

--- Create IPv6 TCP socket
---@return socket_tcp_client* client TCP socket
function M.tcp6() end

--- Create UDP socket
---@return socket_udp_client* client UDP socket
function M.udp() end

--- Create IPv4 UDP socket
---@return socket_udp_client* client UDP socket
function M.udp4() end

--- Create IPv6 UDP socket
---@return socket_udp_client* client UDP socket
function M.udp6() end

--- Connect to TCP service
---@param address string remote address
---@param port integer remote port
---@param laddress? string local address
---@param lport? integer local port
---@param family? 'inet'|'inet6' address family
---@return socket_tcp_client*? client TCP socket
---@return string? errMsg error message
function M.connect(address, port, laddress, lport, family) end

--- Connect to IPv4 TCP service
---@param address string remote address
---@param port integer remote port
---@param laddress? string local address
---@param lport? integer local port
---@return socket_tcp_client*? client TCP socket
---@return string? errMsg error message
function M.connect4(address, port, laddress, lport) end

--- Connect to IPv6 TCP service
---@param address string remote address
---@param port integer remote port
---@param laddress? string local address
---@param lport? integer local port
---@return socket_tcp_client*? client TCP socket
---@return string? errMsg error message
function M.connect6(address, port, laddress, lport) end

--- Bind and listen to the TCP service
---@param host string Listening address, '*' means all IPv4 addresses
---@param port integer listening port
---@param backlog? integer backlog
---@return socket_server*? server service socket
---@return string? errMsg error message
function M.bind(host, port, backlog) end

--- Wait for socket to be readable or writable
---@param recvt? table Readable socket list
---@param sendt? table Writable socket list
---@param timeout? number Timeout seconds
---@return table readable readable list
---@return table writable writable list
---@return string? errMsg error message
function M.select(recvt, sendt, timeout) end

--- current time
---@return number time seconds time
function M.gettime() end

--- Delay for specified number of seconds
---@param seconds number seconds
function M.sleep(seconds) end

--- Create an error protection function
---@param finalizer? function closing function
---@return function try try function
function M.newtry(finalizer) end

--- Protect function calls
---@param func function function
---@return function protected Protected function
function M.protect(func) end

--- Skip the first n return values
---@param count integer skip quantity
---@param ... any value
---@return any ... residual value
function M.skip(count, ...) end

--- Create LTN12 sink
---@param mode? 'close-when-done'|'keep-open' mode
---@param sock socket_tcp_client* socket
---@return function sink sink function
function M.sink(mode, sock) end

--- Create LTN12 source
---@param mode? 'by-length'|'until-closed' mode
---@param sock socket_tcp_client* socket
---@param length? integer Read length
---@return function source source function
function M.source(mode, sock, length) end

--- Select named factory
---@param factory table Factory table
---@return function chooser Select function
function M.choose(factory) end

--- Query host name
---@return string hostname hostname
function socket_dns.gethostname() end

--- Hostname to IP
---@param name string hostname
---@return string? ip IP address
---@return string? errMsg error message
function socket_dns.toip(name) end

--- IP to hostname
---@param address string IP address
---@return string? name hostname
---@return string? errMsg error message
function socket_dns.tohostname(address) end

--- Query address information
---@param host string hostname
---@return table? info Address information list
---@return string? errMsg error message
function socket_dns.getaddrinfo(host) end

--- Connect to remote address
---@param host string remote address
---@param port integer remote port
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:connect(host, port) end

--- Bind local address
---@param host string local address
---@param port integer local port
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:bind(host, port) end

--- Start listening
---@param backlog? integer backlog
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:listen(backlog) end

--- accept connection
---@return socket_tcp_client*? client client socket
---@return string? errMsg error message
function socket_tcp_client:accept() end

--- Send data
---@param data string data
---@param from? integer starting position
---@param to? integer end position
---@return integer? sent Number of bytes sent
---@return string? errMsg error message
---@return integer? lastIndex last sent position
function socket_tcp_client:send(data, from, to) end

--- receive data
---@param pattern? '*l'|'*a'|integer receive mode
---@param prefix? string prefix
---@return string? data data
---@return string? errMsg error message
---@return string? partial partial data
function socket_tcp_client:receive(pattern, prefix) end

--- Set timeout
---@param timeout socket_timeout Timeout seconds
---@param mode? 'b'|'r'|'s' mode
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:settimeout(timeout, mode) end

--- close socket
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:close() end

--- Get local address
---@return string ip IP address
---@return integer port port
---@return string? family address family
function socket_tcp_client:getsockname() end

--- Get remote address
---@return string ip IP address
---@return integer port port
---@return string? family address family
function socket_tcp_client:getpeername() end

--- Set socket options
---@param option string option name
---@param value any option value
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_tcp_client:setoption(option, value) end

--- Get socket options
---@param option string option name
---@return any value option value
---@return string? errMsg error message
function socket_tcp_client:getoption(option) end

--- Send UDP data
---@param data string data
---@return integer? sent Number of bytes sent
---@return string? errMsg error message
function socket_udp_client:send(data) end

--- Send UDP data to the specified address
---@param data string data
---@param ip string IP address
---@param port integer port
---@return integer? sent Number of bytes sent
---@return string? errMsg error message
function socket_udp_client:sendto(data, ip, port) end

--- Receive UDP data
---@param size? integer maximum length
---@return string? data data
---@return string? errMsg error message
function socket_udp_client:receive(size) end

--- Receive UDP data and origin
---@param size? integer maximum length
---@return string? data data
---@return string? ip Source IP
---@return integer? port source port
function socket_udp_client:receivefrom(size) end

--- Set up UDP peer
---@param ip string IP address
---@param port integer port
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_udp_client:setpeername(ip, port) end

--- Set UDP local address
---@param ip string IP address
---@param port integer port
---@return integer? ok Returns 1 on success
---@return string? errMsg error message
function socket_udp_client:setsockname(ip, port) end

return M
