local DR = select(2, ...)
local constants = DR.Modules["Core.Constants"]

local Audit = {}

local function trimAudit()
  local events = DR.db.global.auditEvents
  local cap = constants.LIMITS.AUDIT_EVENTS

  if #events <= cap then
    return
  end

  local overflow = #events - cap
  for _ = 1, overflow do
    table.remove(events, 1)
  end
end

function Audit:OnInitialize()
  DR.db.global.auditEvents = DR.db.global.auditEvents or {}
end

function Audit:Append(eventType, payload)
  local event = {
    ts = time(),
    eventType = eventType,
    payload = payload,
  }

  local events = DR.db.global.auditEvents
  events[#events + 1] = event
  trimAudit()

  local log = DR.logService and DR.logService:Get("Audit")
  if log then
    log:d("Audit event", eventType)
  end

  return event
end

function Audit:GetRecent(limit)
  local events = DR.db.global.auditEvents
  if not limit or limit >= #events then
    return events
  end

  local out = {}
  for i = #events - limit + 1, #events do
    out[#out + 1] = events[i]
  end
  return out
end

function Audit:ExportAsLua(limit)
  local rows = self:GetRecent(limit)
  local out = { "DetentionRollsAudit = {" }

  for _, row in ipairs(rows) do
    out[#out + 1] = string.format("  { ts = %d, eventType = %q },", row.ts, tostring(row.eventType))
  end

  out[#out + 1] = "}"
  return table.concat(out, "\n")
end

DR:RegisterModule("Services.Audit", Audit)
