(local handlers (require :handlers))

(fn send [socket command use-separator? args]
  (var str command)
  (when (> (# args) 0)
    (let [sep (if use-separator?
                  " :"
                  (> (# args) 1)
                  " " "")]
      (set str (.. str " " (table.concat args " " 1 (- (# args) 1))
                   sep (. args (# args))))))
  (when _G.debug?
    (print ">" str))
  (: socket :send (.. str "\r\n")))

(fn push [conn command use-separator? args]
  (tset conn.queue conn.bottom [command use-separator? args])
  (set conn.bottom (+ conn.bottom 1)))

(fn flush [conn]
  (when (not (= conn.top conn.bottom))
    (let [[command separator? args] (. conn.queue conn.top)]
      (tset conn.queue conn.top nil)
      (set conn.top (+ conn.top 1))
      (when (= conn.top conn.bottom)
        (set conn.top 1)
        (set conn.bottom 1))
      (send conn.socket command separator? args))))

(local irc {:commands {} :tokenize tokenize :flush flush})
local handlers = require("handlers")

local function send(socket, command, use_separator_3f, args)
  local str = command
  if (#args > 0) then
    local sep = sep
    if use_separator_3f then
      sep = " :"
    elseif (#args > 1) then
      sep = " "
    else
      sep = ""
    end
    str = (str .. " " .. table.concat(args, " ", 1, (#args - 1)) ..
              sep .. args[#args])
  end
  if _G["debug?"] then
    print(">", str)
  end
  return socket:send((str .. "\13\n"))
end

local function push(conn, command, use_separator_3f, args)
  conn.queue[conn.bottom] = {command, use_separator_3f, args}
  conn.bottom = (conn.bottom + 1)
  return nil
end

local function flush(conn)
  if not (conn.top == conn.bottom) then
    local _0_ = conn.queue[conn.top]
    local command = _0_[1]
    local separator_3f = _0_[2]
    local args = _0_[3]
    conn.queue[conn.top] = nil
    conn.top = (conn.top + 1)
    if (conn.top == conn.bottom) then
      conn.top = 1
      conn.bottom = 1
    end
    return send(conn.socket, command, separator_3f, args)
  end
end

local irc = {commands = {}, flush = flush, tokenize = tokenize}