import { readJson, writeJson } from '../../storage/base-store.js';
import toolGroupsConfigJson from '../../config/tool-groups.json' with { type: 'json' };
const STATE_PATH = 'data/global/tool-group-state.json';
const toolGroupsConfig = toolGroupsConfigJson;
export class GroupManager {
    groups;
    enabledState;
    toolMap;
    notifyChanged;
    constructor(toolMap, notifyChanged) {
        this.toolMap = toolMap;
        this.notifyChanged = notifyChanged;
        this.groups = new Map();
        this.enabledState = new Map();
    }
    /** Load groups from config, restore persisted state, apply to toolMap. */
    async init() {
        for (const def of toolGroupsConfig.groups) {
            this.groups.set(def.id, def);
            this.enabledState.set(def.id, def.defaultEnabled);
        }
        const persisted = await this.loadPersistedState();
        for (const [groupId, enabled] of persisted) {
            if (this.groups.has(groupId)) {
                this.enabledState.set(groupId, enabled);
            }
        }
        for (const [groupId, enabled] of this.enabledState) {
            this.applyGroupState(groupId, enabled);
        }
    }
    /** Enable all tools in a group. */
    enableGroup(groupId) {
        const group = this.groups.get(groupId);
        if (!group) {
            return this.buildErrorResult(groupId, 'enable', `Group '${groupId}' does not exist.`);
        }
        this.enabledState.set(groupId, true);
        this.applyGroupState(groupId, true);
        void this.persistState().catch((err) => {
            console.error('[planu] group-manager persistState failed:', err);
        });
        this.notifyChanged();
        return this.buildActivationResult(groupId, 'enable');
    }
    /** Disable all tools in a group. */
    disableGroup(groupId) {
        const group = this.groups.get(groupId);
        if (!group) {
            return this.buildErrorResult(groupId, 'disable', `Group '${groupId}' does not exist.`);
        }
        if (group.locked) {
            return this.buildErrorResult(groupId, 'disable', `Group '${groupId}' is locked and cannot be disabled.`);
        }
        this.enabledState.set(groupId, false);
        this.applyGroupState(groupId, false);
        void this.persistState().catch((err) => {
            console.error('[planu] group-manager persistState failed:', err);
        });
        this.notifyChanged();
        return this.buildActivationResult(groupId, 'disable');
    }
    /** Toggle a group based on its current state. */
    toggleGroup(groupId) {
        const group = this.groups.get(groupId);
        if (!group) {
            return this.buildErrorResult(groupId, 'toggle', `Group '${groupId}' does not exist.`);
        }
        const currentlyEnabled = this.enabledState.get(groupId) ?? group.defaultEnabled;
        if (!currentlyEnabled) {
            return this.enableGroup(groupId);
        }
        if (group.locked) {
            return this.buildErrorResult(groupId, 'toggle', `Group '${groupId}' is locked and cannot be disabled.`);
        }
        return this.disableGroup(groupId);
    }
    /** Return runtime status for all groups, including a virtual 'ungrouped' group. */
    getGroupStatus() {
        const statuses = [];
        const groupedTools = new Set();
        for (const [groupId, def] of this.groups) {
            for (const tool of def.tools) {
                groupedTools.add(tool);
            }
            const enabled = this.enabledState.get(groupId) ?? def.defaultEnabled;
            statuses.push({
                id: groupId,
                name: def.name,
                description: def.description,
                enabled,
                tools: [...def.tools],
                toolCount: def.tools.length,
            });
        }
        const ungroupedTools = [];
        for (const toolName of this.toolMap.keys()) {
            if (!groupedTools.has(toolName)) {
                ungroupedTools.push(toolName);
            }
        }
        if (ungroupedTools.length > 0) {
            statuses.push({
                id: 'ungrouped',
                name: 'Ungrouped',
                description: 'Tools not assigned to any defined group.',
                enabled: true,
                tools: ungroupedTools,
                toolCount: ungroupedTools.length,
            });
        }
        return statuses;
    }
    /** Return the group ID that contains the given tool, or undefined. */
    getToolGroup(toolName) {
        for (const [groupId, def] of this.groups) {
            if (def.tools.includes(toolName)) {
                return groupId;
            }
        }
        return undefined;
    }
    /** Count of tools currently enabled in toolMap. */
    getActiveToolCount() {
        let count = 0;
        for (const slot of this.toolMap.values()) {
            if (slot.enabled) {
                count++;
            }
        }
        return count;
    }
    /** Total tools registered in toolMap. */
    getTotalToolCount() {
        return this.toolMap.size;
    }
    /** Load persisted group states from disk. */
    async loadPersistedState() {
        const defaultState = { states: [], updatedAt: '' };
        const persisted = await readJson(STATE_PATH, defaultState);
        const result = new Map();
        for (const entry of persisted.states) {
            result.set(entry.groupId, entry.enabled);
        }
        return result;
    }
    /** Write current group states to disk. */
    async persistState() {
        const states = [];
        for (const [groupId, enabled] of this.enabledState) {
            states.push({ groupId, enabled, lastChanged: new Date().toISOString() });
        }
        const payload = {
            states,
            updatedAt: new Date().toISOString(),
        };
        await writeJson(STATE_PATH, payload);
    }
    /** Apply enabled/disabled state to all tools in a group via toolMap. */
    applyGroupState(groupId, enabled) {
        const def = this.groups.get(groupId);
        /* v8 ignore next 3 */
        if (!def) {
            return;
        }
        for (const toolName of def.tools) {
            const slot = this.toolMap.get(toolName);
            if (!slot) {
                continue;
            }
            if (enabled) {
                slot.enable();
            }
            else {
                slot.disable();
            }
        }
    }
    /** Build a successful GroupActivationResult for a given group and action. */
    buildActivationResult(groupId, action) {
        const newState = this.enabledState.get(groupId) ?? false;
        return {
            success: true,
            group: groupId,
            action,
            newState,
            allGroups: this.getGroupStatus(),
            totalActiveTools: this.getActiveToolCount(),
            totalTools: this.getTotalToolCount(),
        };
    }
    /** Build a failed GroupActivationResult (group not found or locked). */
    buildErrorResult(groupId, action, _message) {
        return {
            success: false,
            group: groupId,
            action,
            newState: this.enabledState.get(groupId) ?? false,
            allGroups: this.getGroupStatus(),
            totalActiveTools: this.getActiveToolCount(),
            totalTools: this.getTotalToolCount(),
        };
    }
}
//# sourceMappingURL=group-manager.js.map