--This module is an attempt to add the functionality of automatic suspension to awesome.
--Although it is not supported nor is advised, it should probably work as long as awful.spawn and gears.timer functions don't change
--A known issue: there is a memory leak that is hard to trace
local awful = require("awful")
local gears = require("gears")
local naughty = require("naughty")
local rcfile = io.open(global.config_dir.."powerman.lua")
G_PowerManPIDs = {}
G_PowerManSleepTimer = os.time()
G_PowerManSuspendTimer = os.time()
G_PowerManSleepNotify = os.time()
G_PowerManSuspendNotify = os.time()
G_PowerManTracker = {
    MouseCoords = {}
}
local function pgrep(prg)
    awful.spawn.easy_async("pgrep "..prg,function(out,err,r,code) 
        if out ~= "" then
            G_PowerManPIDs[prg] = true
        else
            G_PowerManPIDs[prg] = nil
        end
    end)
end
if rcfile then
    local sleep_activated,suspend_activated = false,false
    local sleep_notified,suspend_notified = false,false
    --rc file loading
    local rc,err = load(rcfile:read("*a"))
    rcfile:close()
    local rcdata
    if not err then
        rcdata = rc()
    else
        require("naughty").notify({
            title = "Error reading rc.lua",
            text = err
        })
    end
    --disable builtin x11 screensaver timer and dpms timer
    awful.spawn("xset -dpms s off")
    --defaults
    rcdata.sleep_rules = rcdata.sleep_rules or {}
    rcdata.suspend_rules = rcdata.suspend_rules or {}
    rcdata.sleep_time = rcdata.sleep_time or 
        ((type(rcdata.sleep_time) == "nil") and 900)
    rcdata.suspend_time = rcdata.suspend_time or 
        ((type(rcdata.suspend_time) == "nil") and 1800)
    rcdata.sleep = rcdata.sleep or ((type(rcdata.sleep) == "nil") and true)
    rcdata.suspend = rcdata.suspend
    rcdata.sleep_notify = rcdata.sleep_notify or 
        ((type(rcdata.sleep_notify) == "nil") and 600)
    rcdata.suspend_notify = rcdata.suspend_notify
    --main timer
    gears.timer {
        timeout = 10,
        call_now = true,
        autostart = true,
        callback = function()
            if mouse.coords() and
               mouse.coords().x ~= G_PowerManTracker.MouseCoords.x or
               mouse.coords().y ~= G_PowerManTracker.MouseCoords.y then
                G_PowerManSleepTimer = os.time()
                G_PowerManSuspendTimer = os.time()
                G_PowerManSleepNotify = os.time()
                G_PowerManSuspendNotify = os.time()
                sleep_activated = false
                suspend_activated = false
                sleep_notified = false
                suspend_notified = false
            end
            for flags,progname in pairs(rcdata.sleep_rules) do
                pgrep(progname)
                if G_PowerManPIDs[progname] then
                    G_PowerManSleepTimer = os.time() 
                    G_PowerManSleepNotify = os.time()
                end
            end
            for flags,progname in pairs(rcdata.suspend_rules) do
                pgrep(progname)
                if G_PowerManPIDs[progname] then
                    G_PowerManSuspendTimer = os.time()
                    G_PowerManSuspendNotify = os.time()
                end
            end
            if rcdata.sleep_notify and (not sleep_notified) and
               (rcdata.sleep_notify+10 < rcdata.sleep_time) then
                if os.time()-G_PowerManSleepNotify > rcdata.sleep_notify then
                    sleep_notified = true
                    naughty.notify({text="screen will turn off in "..tostring(
                        math.floor((rcdata.sleep_time-rcdata.sleep_notify)/60)
                    ).." minutes"})
                end
            end
            if rcdata.suspend_notify and (not suspend_notified) and
               (rcdata.suspend_notify+10 < rcdata.suspend_time) then
                if os.time()-G_PowerManSuspendNotify>rcdata.suspend_notify then
                    suspend_notified = true
                    naughty.notify({text="Computer will suspend in"..tostring(
                    math.floor((rcdata.suspend_time-rcdata.suspend_notify)/60)
                    ).."minutes"})
                end
            end
            if rcdata.sleep and (not sleep_activated) then
                if os.time()-G_PowerManSleepTimer > rcdata.sleep_time then
                    if rcdata.sleep_lock then
                        rcdata.sleep_lock()
                    end
                    sleep_activated = true
                    awful.spawn("xset s activate dpms suspend")
                end
            end
            if rcdata.suspend and (not suspend_activated) then
                if os.time()-G_PowerManSuspendTimer > rcdata.suspend_time then
                    if rcdata.suspend_lock then
                        rcdata.suspend_lock()
                    end
                    suspend_activated = true
                    awful.spawn.with_shell("systemctl suspend || loginctl suspend")
                end
            end
            G_PowerManTracker.MouseCoords = mouse.coords() or {}
        end
    }
end
