-- factoryos.sdk — the public authoring surface for modules & apps.
-- Modules return sdk.module{...}; the controller runtime does the rest.

local M = {}

local function isOp(v) return type(v) == "function" or type(v) == "table" end

--- Validate + normalize a module manifest. Errors fail fast at load time.
function M.module(m)
  assert(type(m) == "table", "manifest must be a table")
  assert(type(m.id) == "string", "manifest.id required")
  assert(type(m.version) == "string", "manifest.version required")
  m.requires = m.requires or {}
  m.services = m.services or {}
  m.failsafe = m.failsafe or "continue"
  assert(m.failsafe == "continue" or m.failsafe == "safe",
    "failsafe must be 'continue' or 'safe'")
  for svc, def in pairs(m.services) do
    assert(type(def) == "table" and type(def.ops) == "table",
      "service " .. svc .. " needs ops table")
    for op, spec in pairs(def.ops) do
      assert(isOp(spec), svc .. "." .. op .. " must be fn or {fn,level}")
    end
  end
  return m
end

--- Declare an app for the desktop shell.
function M.app(a)
  assert(type(a) == "table" and a.id and a.name and a.create,
    "app needs id, name, create")
  return a
end

return M
