-- VDS_Selectors
-- ============================================================================
-- Selector registry. Selectors are pure functions of (state, ctx). They
-- declare `reads` (state paths) + `calls` (other selectors) so the
-- BindingEngine can compute the transitive reads-closure for each bound
-- widget.

VDS = VDS or {}
VDS.Selectors = VDS.Selectors or { _registry = {} }

local Selectors = VDS.Selectors
local Paths = VDS.Paths

function Selectors:Register(name, spec)
    -- spec: { reads = {...}, calls = {...}, fn = function(state, ctx) ... end }
    self._registry[name] = spec
end

function Selectors:Get(name) return self._registry[name] end

function Selectors:Call(name, state, ctx)
    local spec = self._registry[name]
    if not spec then error("Selectors:Call: unknown selector " .. tostring(name), 2) end
    -- per-selector call counter (diagnostic)
    self._callCounts = self._callCounts or {}
    self._callCounts[name] = (self._callCounts[name] or 0) + 1
    return spec.fn(state, ctx)
end

-- Returns the transitive reads-closure for a selector: union of its own
-- `reads` + every selector it `calls` (recursively).
function Selectors:GetReads(name)
    local spec = self._registry[name]
    if not spec then return {} end
    local out = {}
    for _, p in ipairs(spec.reads or {}) do out[p] = true end
    for _, sub in ipairs(spec.calls or {}) do
        local subReads = self:GetReads(sub)
        for p in pairs(subReads) do out[p] = true end
    end
    return out
end
