import { readdir } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import { CliError } from '../errors/index.js';
import { resolveAssetsRoot } from '../fs/assets.js';
import { SCOPE_CONTENT_TYPES, USER_SCOPE_MANAGED_AGENT_FILES, } from '../shared/types.js';
function canonicalDirectoryName(contentType) {
    if (contentType === 'skill') {
        return 'skills';
    }
    if (contentType === 'agent') {
        return 'agents';
    }
    return 'rules';
}
async function readEntries(dirPath) {
    try {
        const entries = await readdir(dirPath, { withFileTypes: true });
        const results = [];
        for (const entry of entries) {
            if (entry.isDirectory()) {
                results.push({ name: entry.name, isFile: false });
            }
            else if (entry.isFile() && entry.name.endsWith('.md')) {
                results.push({ name: entry.name, isFile: true });
            }
        }
        results.sort((left, right) => left.name.localeCompare(right.name));
        return results;
    }
    catch (error) {
        if (typeof error === 'object' &&
            error !== null &&
            'code' in error &&
            error.code === 'ENOENT') {
            return [];
        }
        if (typeof error === 'object' &&
            error !== null &&
            'code' in error &&
            (error.code === 'EACCES' || error.code === 'EPERM')) {
            throw new CliError(`Permission denied reading canonical directory ${dirPath}. Adjust permissions and retry.`);
        }
        throw error;
    }
}
export async function scanBundledManagedAgents() {
    const agentsDir = join(await resolveAssetsRoot(), 'agents');
    const entries = await readEntries(agentsDir);
    const available = new Set(entries.filter((entry) => entry.isFile).map((entry) => entry.name));
    const missing = USER_SCOPE_MANAGED_AGENT_FILES.filter((name) => !available.has(name));
    if (missing.length > 0) {
        throw new CliError(`Bundled managed role definitions are unavailable: ${missing.join(', ')}. Reinstall or rebuild OAT before running user sync.`);
    }
    return USER_SCOPE_MANAGED_AGENT_FILES.map((name) => ({
        name,
        type: 'agent',
        canonicalPath: join(agentsDir, name),
        isFile: true,
    }));
}
/** @deprecated Use scanBundledManagedAgents for provider-neutral materialization. */
export const scanBundledManagedCodexAgents = scanBundledManagedAgents;
export async function scanCanonical(basePath, scope) {
    const scopeRoot = resolve(basePath);
    const entries = [];
    for (const contentType of SCOPE_CONTENT_TYPES[scope]) {
        const contentDir = join(scopeRoot, '.agents', canonicalDirectoryName(contentType));
        const includeFiles = contentType === 'agent' || contentType === 'rule';
        const scanned = await readEntries(contentDir);
        for (const scannedEntry of scanned) {
            if (scannedEntry.isFile && !includeFiles) {
                continue;
            }
            entries.push({
                name: scannedEntry.name,
                type: contentType,
                canonicalPath: join(contentDir, scannedEntry.name),
                isFile: scannedEntry.isFile,
            });
        }
    }
    return entries;
}
