-- According to the IMAP specification, when trying to write a message
-- to a non-existent mailbox, the server must send a hint to the client,
-- whether it should create the mailbox and try again or not. However
-- some IMAP servers don't follow the specification and don't send the
-- correct response code to the client. By enabling this option the
-- client tries to create the mailbox, despite of the server's response.
-- This variable takes a boolean as a value.  Default is “false”.
options.create = true
-- By enabling this option new mailboxes that were automatically created,
-- get auto subscribed
options.subscribe = true
-- How long to wait for servers response.
options.timeout = 120

-- whether to enter IDLE mode and conintuously check
-- for new incoming mail to filter
CONTINUOUS = false
-- time to wait for next synchronization
-- only used in case server does not support IDLE mode
UPDATE_TIME = 120

-- implement simple wait function in case server does not support IDLE mode
function sleep(n)
	os.execute("sleep " .. tonumber(n))
end

-- will set filters to be grabbed from XDG-compliant filter directory
-- can be overridden with env var IMAPFILTER_FILTERDIR
function getConfigDir()
	-- -- set directory for imapfilter files
	local configdir
	if os.getenv("IMAPFILTER_CONFIGDIR") then
		configdir = os.getenv("IMAPFILTER_CONFIGDIR")
	elseif os.getenv("XDG_CONFIG_HOME") then
		configdir = os.getenv("XDG_CONFIG_HOME") .. "/imapfilter"
	else
		configdir = os.getenv("HOME") .. "/.config/imapfilter"
	end
	return configdir
end

-- will set filters to be grabbed from XDG-compliant filter directory
-- can be overridden with env var IMAPFILTER_FILTERDIR
function getFilterDir()
	-- -- set directory for imapfilter files
	local imapfilterdir
	if os.getenv("IMAPFILTER_FILTERDIR") then
		imapfilterdir = os.getenv("IMAPFILTER_FILTERDIR")
	else
		imapfilterdir = configDir .. "/filters"
	end
	return imapfilterdir
end

-- dirlist, from https://stackoverflow.com/a/25266573
function applyFilters(dir)
	local p = io.popen('find "' .. dir .. '" -type f -name "*.lua"') -- Open directory look for files, save data in p. By giving '-type f' as parameter, it returns all files.
	for file in p:lines() do -- Loop through all files
		loadfile(file)()
	end
end

-- create global variable containing the configuration files
configDir = getConfigDir()
assert(configDir, "No configuration directory found. Ensure " .. os.getenv("HOME") .. "/.config/imapfilter exists.")

-- create global variable containing account access
accounts = loadfile(configDir .. "/accounts.lua")()
assert(accounts, "No accounts configured. Ensure accounts.lua exists and returns a table of accounts.")

-- immediately act on the filters once
applyFilters(getFilterDir())

-- continuously watch for mail if needed
while CONTINUOUS == true do
	local has_idle = accounts.gmail["Inbox"]:enter_idle()
	applyFilters(getFilterDir())

	if has_idle == false then
		print("Server does not support idle, application will be polling again in " .. UPDATE_TIME .. "minutes.")
		sleep(UPDATE_TIME)
	end
end
