-- factoryos.drivers.redstoneout — named redstone outputs.
-- Output values may be:
--   "left"                          → computer side via redstone API
--   { p = "redstoneIntegrator_3", side = "north" }  → AP integrator
-- A driver instance owns the outputs table; callers address by name only.

local M = {}

local function targetFor(spec)
  if type(spec) == "string" then return { kind = "side", side = spec } end
  if type(spec) == "table" and spec.p and spec.side then
    return { kind = "integ", p = spec.p, side = spec.side }
  end
end

function M.new(outputs)
  return { outputs = outputs or {} }
end

function M.set(self, name, state)
  local t = targetFor(self.outputs[name])
  if not t then return false, "no_such_output:" .. tostring(name) end
  state = not not state
  if t.kind == "side" then
    redstone.setOutput(t.side, state)
    return true, redstone.getOutput(t.side)
  end
  local ok, err = pcall(peripheral.call, t.p, "setOutput", t.side, state)
  if not ok then return false, "peripheral:" .. tostring(err) end
  local okR, obs = pcall(peripheral.call, t.p, "getOutput", t.side)
  return true, okR and obs or state
end

function M.get(self, name)
  local t = targetFor(self.outputs[name])
  if not t then return false, "no_such_output:" .. tostring(name) end
  if t.kind == "side" then return true, redstone.getOutput(t.side) end
  local ok, v = pcall(peripheral.call, t.p, "getOutput", t.side)
  return ok, ok and v or nil
end

function M.toggle(self, name)
  local ok, cur = M.get(self, name)
  if not ok then return false, cur end
  return M.set(self, name, not cur)
end

function M.list(self)
  local out = {}
  for name, spec in pairs(self.outputs) do
    local _, state = M.get(self, name)
    out[#out + 1] = { name = name,
      side = type(spec) == "string" and spec or (spec.p .. ":" .. spec.side),
      state = state == true }
  end
  table.sort(out, function(a, b) return a.name < b.name end)
  return out
end

--- Advanced Peripherals redstoneIntegrators on this node (for config UI).
function M.integrators()
  local out = {}
  for _, p in ipairs({ peripheral.find("redstoneIntegrator") }) do
    out[#out + 1] = peripheral.getName(p)
  end
  return out
end

return M
