--[[
Utility module for Alpine Wall
Copyright (C) 2012-2021 Kaarle Ritvanen
See LICENSE file for license details
]]--


local M = {}

local lpc = require('lpc')


function M.split(s, sep)
	if s == '' then return {} end
	local res = {}
	while true do
		local si, ei = s:find(sep, 1, true)
		if not si then
			table.insert(res, s)
			return res
		end
		table.insert(res, s:sub(1, si - 1))
		s = s:sub(ei + 1, -1)
	end
end

function M.list(var)
	if not var then return {} end
	if type(var) ~= 'table' then return {var} end
	if not next(var) then return {} end
	return var[1] and var or {var}
end

function M.listpairs(var) return ipairs(M.list(var)) end

function M.filter(var, func)
	local res = {}
	for i, v in ipairs(var) do if func(v) then table.insert(res, v) end end
	return res
end

function M.map(var, func)
	local res = {}
	for k, v in pairs(var) do res[k] = func(v) end
	return res
end

function M.maplist(var, func)
	if not var then return var end
	return M.map(M.list(var), func)
end

function M.contains(tbl, value)
	for k, v in M.listpairs(tbl) do if v == value then return true end end
	return false
end

function M.keys(tbl)
	local res = {}
	for k, v in pairs(tbl) do table.insert(res, k) end
	return res
end

function M.values(tbl)
	local res = {}
	for k, v in pairs(tbl) do table.insert(res, v) end
	return res
end

function M.sortedkeys(tbl)
	local res = M.keys(tbl)
	table.sort(res)
	return ipairs(res)
end

function M.extend(tbl1, tbl2)
	for i, var in M.listpairs(tbl2) do table.insert(tbl1, var) end
	return tbl1
end

function M.update(tbl1, tbl2)
	if tbl2 then for k, v in pairs(tbl2) do tbl1[k] = v end end
	return tbl1
end

function M.setdefault(t, k, v)
	if t[k] == nil then t[k] = v end
	return t[k]
end

function M.copy(var)
	return type(var) == 'table' and M.update({}, var) or var
end

function M.compare(a, b)
	local t = type(a)
	if t ~= type(b) then return false end
	if t ~= 'table' then return a == b end

	local keys = {}
	for k, v in pairs(a) do
		if not M.compare(v, b[k]) then return false end
		table.insert(keys, k)
	end
	for k, v in pairs(b) do
		if not M.contains(keys, k) then return false end
	end
	return true
end

function M.join(a, sep, b)
	local comps = {}
	local function add(s)
		if not s then return end
		s = tostring(s)
		if s > '' then table.insert(comps, s) end
	end
	add(a)
	add(b)
	if comps[1] then return table.concat(comps, sep) end
end


function M.startswithupper(s)
	if s == '' then return false end
	local c = s:sub(1, 1)
	return c == c:upper()
end

function M.quote(s) return '"'..s:gsub('(["\\])', '\\%1')..'"' end


function M.printtabulars(tables)
	local colwidth = {}
	for i, tbl in ipairs(tables) do
		for j, row in ipairs(tbl) do
			for k, col in ipairs(row) do
				colwidth[k] = math.max(colwidth[k] or 0, col:len())
			end
		end
	end
	for i, tbl in ipairs(tables) do
		for j, row in ipairs(tbl) do
			for k = 1,#row do
				if k > 1 then io.write('  ') end
				io.write(row[k])
				if k < #row then
					for l = 1,colwidth[k] - row[k]:len() do io.write(' ') end
				end
			end
			io.write('\n')
		end
		io.write('\n')
	end
end

function M.printtabular(tbl) M.printtabulars({tbl}) end


function M.printmsg(msg) io.stderr:write(msg..'\n') end


function M.run(...)
	local pid, stdin, stdout = lpc.run(...)
	stdin:close()
	stdout:close()
	return pid
end

function M.execute(...) return lpc.wait(M.run(...)) end

return M

-- vim: ts=4
