-- VDS_Paths
-- ============================================================================
-- State-path utilities ("account.config.scheme" strings). Used by action meta
-- invalidates, BindingEngine reads-closures, and Selector reads declarations.

VDS = VDS or {}
VDS.Paths = VDS.Paths or {}

local Paths = VDS.Paths

-- ViewSlot("category", "selectedDyeID") -> "session.ui.byView.category.selectedDyeID"
-- Used by action-meta invalidates functions to build per-tab path strings.
function Paths.ViewSlot(view, key)
    return "session.ui.byView." .. view .. "." .. key
end

-- Join("account.foo", "bar") -> "account.foo.bar"
function Paths.Join(prefix, suffix)
    if not suffix or suffix == "" then return prefix end
    if not prefix or prefix == "" then return suffix end
    return prefix .. "." .. suffix
end

-- Union(set1, set2) -> set with both. "*" wildcard short-circuits.
function Paths.Union(a, b)
    if a == "*" or b == "*" then return "*" end
    local out = {}
    if type(a) == "table" then for k, v in pairs(a) do out[k] = v end end
    if type(b) == "table" then
        for _, p in ipairs(b) do out[p] = true end
    end
    return out
end

-- MatchesAny(readsClosure, invalidation) -> bool
-- readsClosure: "*" | {[path]=true} | {array}; invalidation: "*" | {array}
function Paths.MatchesAny(readsClosure, invalidation)
    if readsClosure == "*" or invalidation == "*" then return true end
    if type(readsClosure) ~= "table" or type(invalidation) ~= "table" then return false end
    -- Normalise readsClosure to a set
    local set = readsClosure
    if set[1] ~= nil then
        local s = {}
        for _, p in ipairs(set) do s[p] = true end
        set = s
    end
    for _, p in ipairs(invalidation) do
        if set[p] then return true end
        -- Prefix match: invalidation of "account.ui.foo" matches a read of "account.ui"
        for declared in pairs(set) do
            if declared:sub(1, #p + 1) == p .. "." or
               p:sub(1, #declared + 1) == declared .. "." then
                return true
            end
        end
    end
    return false
end
