#!/usr/bin/env lua -- -- xB seen plugin -- -- Copyright 2016 Přemysl Eric Janouch
-- See the file LICENSE for licensing information.
--
function parse (line)
	local msg = { params = {} }
	line = line:match ("[^\r]*")
	for start, word in line:gmatch ("()([^ ]+)") do
		local colon = word:match ("^:(.*)")
		if start == 1 and colon then
			msg.prefix = colon
		elseif not msg.command then
			msg.command = word
		elseif colon then
			table.insert (msg.params, line:sub (start + 1))
			break
		elseif start ~= #line then
			table.insert (msg.params, word)
		end
	end
	return msg
end
function get_config (name)
	io.write ("XB get_config :", name, "\r\n")
	return parse (io.read ()).params[1]
end
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
io.output ():setvbuf ('line')
local prefix = get_config ('prefix')
io.write ("XB register\r\n")
local db = {}
local db_filename = "seen.db"
local db_garbage = 0
function remember (who, where, when, what)
	if not db[who] then db[who] = {} end
	if db[who][where] then db_garbage = db_garbage + 1 end
	db[who][where] = { tonumber (when), what }
end
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
local db_file, e = io.open (db_filename, "a+")
if not db_file then error ("cannot open database: " .. e, 0) end
function db_store (who, where, when, what)
	db_file:write (string.format
		(":%s %s %s %s :%s\n", who, "PRIVMSG", where, when, what))
end
function db_compact ()
	db_file:close ()
	-- Unfortunately, default Lua doesn't have anything like mkstemp()
	local db_tmpname = db_filename .. "." .. os.time ()
	db_file, e = io.open (db_tmpname, "a+")
	if not db_file then error ("cannot save database: " .. e, 0) end
	for who, places in pairs (db) do
		for where, data in pairs (places) do
			db_store (who, where, data[1], data[2])
		end
	end
	db_file:flush ()
	local ok, e = os.rename (db_tmpname, db_filename)
	if not ok then error ("cannot save database: " .. e, 0) end
	db_garbage = 0
end
for line in db_file:lines () do
	local msg = parse (line)
	remember (msg.prefix, table.unpack (msg.params))
end
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function seen (who, where, args)
	local respond = function (...)
		local privmsg = function (target, ...)
			io.write ("PRIVMSG ", target, " :", table.concat { ... }, "\r\n")
		end
		if where:match ("^[#&!+]") then
			privmsg (where, who, ": ", ...)
		else
			privmsg (who, ...)
		end
	end
	local whom, e, garbage = args:match ("^(%S+)()%s*(.*)")
	if not whom or #garbage ~= 0 then
		return respond ("usage: