-- Read the tiny kernel meminfo pseudo-file every five seconds.  This avoids a
-- resident helper process and reuses Noctalia's lightweight widget lifecycle.
local command = [[awk '
$1 == "MemTotal:" { total = $2 }
$1 == "MemAvailable:" { available = $2 }
$1 == "SwapTotal:" { swap_total = $2 }
$1 == "SwapFree:" { swap_free = $2 }
END {
  if (!total || !available) exit 1
  used = total - available
  memory_used = used * 100 / total
  if (swap_total > 0) {
    swap_used = (swap_total - swap_free) * 100 / swap_total
    printf "%.1f/%.1f GiB  S %.0f%%\t%.0f\t%.0f\n", used / 1048576, total / 1048576, swap_used, memory_used, swap_used
  } else {
    printf "%.1f/%.1f GiB  S —\t%.0f\t0\n", used / 1048576, total / 1048576, memory_used
  }
}' /proc/meminfo]]

local request_in_flight = false

local function colorForUsage(percent)
  if percent >= 85 then
    return "#ff453a" -- red
  end
  if percent >= 70 then
    return "#ff8800" -- orange
  end
  if percent >= 50 then
    return "#ffd60a" -- yellow
  end
  return "#ffffff" -- white
end

local function renderStatus(text, color)
  barWidget.render(ui.row({ gap = 4, align = "center" }, {
    ui.glyph({ name = "memory", size = 14, color = color }),
    ui.label({ text = text, color = color }),
  }))
end

function update()
  noctalia.setUpdateInterval(5000)

  if request_in_flight then
    return
  end

  request_in_flight = true
  noctalia.runAsync(command, function(result)
    request_in_flight = false

    if result.exitCode ~= 0 then
      renderStatus("RAM —", "#fff1e6")
      barWidget.setTooltip("Unable to read /proc/meminfo")
      return
    end

    local text, memory_percent, swap_percent = string.match(
      result.stdout,
      "^([^\t]+)\t([%d.]+)\t([%d.]+)"
    )
    memory_percent = tonumber(memory_percent)
    swap_percent = tonumber(swap_percent)

    if text == nil or memory_percent == nil or swap_percent == nil then
      renderStatus("RAM —", "#fff1e6")
      barWidget.setTooltip("Unable to parse memory utilization")
      return
    end

    local highest_usage = math.max(memory_percent, swap_percent)
    renderStatus(text, colorForUsage(highest_usage))
    barWidget.setTooltip(
      string.format(
        "RAM used / total · %.0f%% RAM · %.0f%% swap",
        memory_percent,
        swap_percent
      )
    )
  end)
end
