local cqueues = require'cqueues'
local socket = require'cqueues.socket'
local openssl_context = require'openssl.ssl.context'
local base64 = require'base64'



local get_default_ehlo_host = function()
  return 'debian' -- TODO read from /etc/hosts
end

local send_auth_plain = function(opts)
  if opts.host==nil or opts.from==nil or opts.to==nil then error('`host`, `from`, and `to` are required.') end

  local host = opts.host
  local port = opts.port or 25 --587
  local username = opts.username
  local password = opts.password

  local ehlo_host = opts.ehlo_host or get_default_ehlo_host()

  local from = opts.from
  local to = opts.to
  -- `message` includes Subject and other headers. Use stmp-message.lua to construct a message string.
  local message = opts.message or 'Subject: \r\n\r\n\r\n.\r\n'
  --local subject = opts.subject or ''
  --local body = opts.body or ''
  
  local connection = socket.connect(host, port)
  connection:settimeout(5)

  local read = function()
    local m = connection:read('*l') or ''
    print('<-- '..m)
    return m
  end

  local read_until = function(code_desired, substring)
    local substring_needed = (substring ~= nil)
    local code, line
    repeat
      line = read()
      code = string.sub(line,1,3)
    until code == code_desired and (not substring_needed or line:find(substring) ~= nil)
  end

  local write = function(m)
    print('--> '..m)
    connection:write(m)
  end

  read_until('220')
  write('STARTTLS\r\n')

  read_until('220')
  local ctx = openssl_context.new('TLSv1_2', false)

  local ok, err = connection:starttls(ctx)
  if not ok then print('starttls error', err) end

  write('EHLO '..ehlo_host..'\r\n')
  read_until('250','PLAIN')

  write('AUTH PLAIN '..base64.encode(username..'\0'..username..'\0'..password)..'\r\n')

  read_until('235') -- auth successful
  write('MAIL FROM:<'..from..'>\r\n')
  read_until('250')
  write('RCPT TO:<'..to..'>\r\n')
  read_until('250')
  write('DATA\r\n')
  read_until('354')
  write(message)
  --write('Subject: '..subject..'\r\n\r\n')
  --write(body..'\r\n')
  write('\r\n.\r\n')
  read_until('250')
  write('QUIT')
  --read_until('221')
  connection:close()
end

return send_auth_plain
