import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
import { CORE_SKILLS } from '../../init/tools/core/install-core.js';
import { DOCS_SKILLS } from '../../init/tools/docs/install-docs.js';
import { IDEA_SKILLS } from '../../init/tools/ideas/install-ideas.js';
import { RESEARCH_AGENTS, RESEARCH_SKILLS, } from '../../init/tools/research/install-research.js';
import { BRAINSTORM_SKILLS, PROJECT_MANAGEMENT_SKILLS, } from '../../init/tools/shared/skill-manifest.js';
import { compareVersions } from '../../init/tools/shared/version.js';
import { UTILITY_SKILLS } from '../../init/tools/utility/install-utility.js';
import { WORKFLOW_AGENTS, WORKFLOW_SKILLS, } from '../../init/tools/workflows/install-workflows.js';
import { getAgentVersion, getSkillVersion } from '../../shared/frontmatter.js';
import { dirExists, fileExists } from '../../../fs/io.js';
const defaultDependencies = {
    getSkillVersion,
    getAgentVersion,
    readdir: async (path) => {
        try {
            const entries = await readdir(path, { withFileTypes: true });
            return entries
                .filter((entry) => entry.isDirectory())
                .map((entry) => entry.name);
        }
        catch {
            return [];
        }
    },
    readdirFiles: async (path, extension) => {
        try {
            const entries = await readdir(path, { withFileTypes: true });
            return entries
                .filter((entry) => entry.isFile() && entry.name.endsWith(extension))
                .map((entry) => entry.name);
        }
        catch {
            return [];
        }
    },
    dirExists,
    fileExists,
};
function resolveSkillPack(name) {
    if (CORE_SKILLS.includes(name))
        return 'core';
    if (IDEA_SKILLS.includes(name))
        return 'ideas';
    if (DOCS_SKILLS.includes(name))
        return 'docs';
    if (WORKFLOW_SKILLS.includes(name))
        return 'workflows';
    if (UTILITY_SKILLS.includes(name))
        return 'utility';
    if (PROJECT_MANAGEMENT_SKILLS.includes(name))
        return 'project-management';
    if (RESEARCH_SKILLS.includes(name))
        return 'research';
    if (BRAINSTORM_SKILLS.includes(name))
        return 'brainstorm';
    return 'custom';
}
function resolveAgentPack(filename) {
    if (WORKFLOW_AGENTS.includes(filename))
        return 'workflows';
    if (RESEARCH_AGENTS.includes(filename))
        return 'research';
    return 'custom';
}
function resolveStatus(installedVersion, bundledVersion) {
    if (bundledVersion === null)
        return 'not-bundled';
    return compareVersions(installedVersion, bundledVersion);
}
export async function scanTools(options) {
    const deps = options.dependencies ?? defaultDependencies;
    const tools = [];
    // Scan skills
    const skillsDir = join(options.scopeRoot, '.agents', 'skills');
    const skillDirs = await deps.readdir(skillsDir);
    for (const skillName of skillDirs) {
        const installedPath = join(skillsDir, skillName);
        const bundledPath = join(options.assetsRoot, 'skills', skillName);
        const pack = resolveSkillPack(skillName);
        const installedVersion = await deps.getSkillVersion(installedPath);
        const hasBundled = await deps.dirExists(bundledPath);
        const bundledVersion = hasBundled
            ? await deps.getSkillVersion(bundledPath)
            : null;
        tools.push({
            name: skillName,
            type: 'skill',
            scope: options.scope,
            version: installedVersion,
            bundledVersion,
            pack,
            status: hasBundled
                ? resolveStatus(installedVersion, bundledVersion)
                : 'not-bundled',
        });
    }
    // Scan agents (project scope only)
    if (options.scope === 'project') {
        const agentsDir = join(options.scopeRoot, '.agents', 'agents');
        const agentsDirExists = await deps.dirExists(agentsDir);
        if (agentsDirExists) {
            const agentFiles = await deps.readdirFiles(agentsDir, '.md');
            for (const agentFile of agentFiles) {
                const installedPath = join(agentsDir, agentFile);
                const bundledPath = join(options.assetsRoot, 'agents', agentFile);
                const pack = resolveAgentPack(agentFile);
                const installedVersion = await deps.getAgentVersion(installedPath);
                const hasBundled = await deps.fileExists(bundledPath);
                const bundledVersion = hasBundled
                    ? await deps.getAgentVersion(bundledPath)
                    : null;
                const name = agentFile.replace(/\.md$/, '');
                tools.push({
                    name,
                    type: 'agent',
                    scope: options.scope,
                    version: installedVersion,
                    bundledVersion,
                    pack,
                    status: hasBundled
                        ? resolveStatus(installedVersion, bundledVersion)
                        : 'not-bundled',
                });
            }
        }
    }
    return tools;
}
