// stack-activator.ts — SPEC-568: Smart tool activation based on detected project stack.
// Pure (no I/O): maps detected stack keywords to group activation changes.
import toolGroupProfilesJson from '../../config/tool-group-profiles.json' with { type: 'json' };
const profilesConfig = toolGroupProfilesJson;
/**
 * Compute which groups should be enabled/disabled given a detected stack.
 *
 * - Matches each profile `signal` against the normalized (lowercased) detected
 *   stack keywords (case-insensitive).
 * - Only returns changes: groups already in the desired state are omitted.
 * - Never requests disabling a group whose `enabled` state is already false.
 * - Never requests disabling a locked group (caller also enforces this via
 *   GroupManager, but we filter early to keep output intent-accurate).
 * - De-duplicates group IDs and never reports a group in both lists; when a
 *   group is requested for both enable and disable, enable wins.
 */
export function computeGroupActivations(detectedStack, currentGroups) {
    if (detectedStack.length === 0 || profilesConfig.profiles.length === 0) {
        return { toEnable: [], toDisable: [] };
    }
    const stackSet = buildStackSet(detectedStack);
    const matchingProfiles = profilesConfig.profiles.filter((profile) => stackSet.has(profile.signal.toLowerCase()));
    if (matchingProfiles.length === 0) {
        return { toEnable: [], toDisable: [] };
    }
    const requestedEnable = collectGroupIds(matchingProfiles, 'enable');
    const requestedDisable = collectGroupIds(matchingProfiles, 'disable');
    // enable wins over disable when a group appears in both
    for (const id of requestedEnable) {
        requestedDisable.delete(id);
    }
    const groupIndex = indexGroups(currentGroups);
    const toEnable = [];
    const toDisable = [];
    for (const id of requestedEnable) {
        const current = groupIndex.get(id);
        // Skip unknown groups and groups already enabled.
        if (!current || current.enabled) {
            continue;
        }
        toEnable.push(id);
    }
    for (const id of requestedDisable) {
        const current = groupIndex.get(id);
        if (!current?.enabled) {
            continue;
        }
        toDisable.push(id);
    }
    return { toEnable, toDisable };
}
function buildStackSet(detectedStack) {
    const set = new Set();
    for (const entry of detectedStack) {
        if (typeof entry === 'string' && entry.length > 0) {
            set.add(entry.toLowerCase());
        }
    }
    return set;
}
function collectGroupIds(profiles, key) {
    const ids = new Set();
    for (const profile of profiles) {
        for (const id of profile[key]) {
            if (typeof id === 'string' && id.length > 0) {
                ids.add(id);
            }
        }
    }
    return ids;
}
function indexGroups(groups) {
    const map = new Map();
    for (const g of groups) {
        map.set(g.id, g);
    }
    return map;
}
//# sourceMappingURL=stack-activator.js.map