-- Sum each logical CPU's interval utilization.  Unlike the built-in average,
-- this follows Unix tools by allowing the value to exceed 100%.
local command = [[awk '
/^cpu[0-9]+ / {
  total = 0
  for (i = 2; i <= NF; i++) total += $i
  idle = $5 + $6
  printf "%s %.0f %.0f\n", $1, total, idle
}' /proc/stat]]

local previous = {}
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 = "cpu", size = 14, color = color }),
    ui.label({ text = text, color = color }),
  }))
end

function update()
  noctalia.setUpdateInterval(2000)

  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("CPU —", "#fff1e6")
      barWidget.setTooltip("Unable to read CPU utilization")
      return
    end

    local utilization = 0
    local sampled = 0
    for line in string.gmatch(result.stdout, "[^\r\n]+") do
      local name, total, idle = string.match(line, "^(cpu%d+) (%d+) (%d+)$")
      total = tonumber(total)
      idle = tonumber(idle)
      local prior = previous[name]

      if prior ~= nil then
        local total_delta = total - prior.total
        local idle_delta = idle - prior.idle
        if total_delta > 0 then
          utilization = utilization + (100 * (total_delta - idle_delta) / total_delta)
          sampled = sampled + 1
        end
      end

      previous[name] = { total = total, idle = idle }
    end

    if sampled > 0 then
      -- Keep the aggregate display, but base its heat color on average
      -- utilization per logical CPU so multicore systems do not stay red.
      local per_cpu_utilization = utilization / sampled
      renderStatus(string.format("%.0f%%", utilization), colorForUsage(per_cpu_utilization))
      barWidget.setTooltip(
        string.format(
          "Aggregate CPU utilization (100%% per logical CPU) · %.0f%% average per CPU",
          per_cpu_utilization
        )
      )
    else
      renderStatus("—", "#fff1e6")
      barWidget.setTooltip("Sampling CPU utilization…")
    end
  end)
end
