local yield, wrap = coroutine.yield, coroutine.wrap

local M = setmetatable({}, {__index = require("libstatgrab")})

function M.startup()
    if M.init() ~= 0 or M.drop_privileges() ~= 0 then
        error(M.str_error(M.get_error()))
    end
end

local t = {
    "host_info",
    "cpu_stats",
    "cpu_stats_diff",
    "cpu_percents",
    "mem_stats",
    "load_stats",
    "user_stats",
    "swap_stats",
    "page_stats",
    "page_stats_diff",
    "process_count"
}

for _,v in ipairs(t) do
    M[v] =  function ()
                local r = assert(M["get_".. v](), M.str_error(M.get_error()))
                return r
            end
end

t = {
    fs_stats = "device_name",
    disk_io_stats = "disk_name",
    disk_io_stats_diff = "disk_name",
    network_io_stats = "interface_name",
    network_io_stats_diff = "interface_name",
    network_iface_stats = "interface_name",
    process_stats = "process_name"
}

local MT = {}

function MT.match( t, pat, field )
    field = field or t.DEFAULTFIELD
    for _,v in ipairs(t) do
        if tostring(v[field]):match(pat) then
            return v
        end
    end
end

function MT.gmatch( t, pat, field )
    field = field or t.DEFAULTFIELD
    return wrap(function ()
                    for _,v in ipairs(t) do
                        if tostring(v[field]):match(pat) then
                            yield(v)
                        end
                    end
                end
            )
end

for k,v in pairs(t) do
    MT[k] = {
        __index = {
            DEFAULTFIELD = v,
            match = MT.match,
            gmatch = MT.gmatch
        }
    }
    M[k] =  function ()
                local r = assert(M["get_".. k](), M.str_error(M.get_error()))
                return setmetatable(r, MT[k])
            end
end

M.MT = MT
return M
