/**
 * Convert slash-command markdown files into Codex skills for Codex releases
 * that no longer load the legacy prompts/ directory.
 */
import * as fs from 'fs';
import * as path from 'path';
import * as yaml from 'yaml';
import { supports } from './capabilities.js';
import { safeJoin } from './paths.js';
const COMMAND_SKILL_MARKER = 'agents_command';
function readCommandMetadata(sourcePath) {
    const content = fs.readFileSync(sourcePath, 'utf-8');
    const lines = content.split('\n');
    if (lines[0] !== '---') {
        return { description: '', body: content };
    }
    const endIndex = lines.slice(1).findIndex((line) => line === '---');
    if (endIndex < 0) {
        return { description: '', body: content };
    }
    const frontmatterEnd = endIndex + 1;
    const frontmatter = lines.slice(1, frontmatterEnd).join('\n');
    const body = lines.slice(frontmatterEnd + 1).join('\n').trimStart();
    try {
        const parsed = yaml.parse(frontmatter);
        const description = typeof parsed?.description === 'string' ? parsed.description.trim() : '';
        return { description, body };
    }
    catch {
        return { description: '', body };
    }
}
function readSkillCommandMarker(skillMdPath) {
    if (!fs.existsSync(skillMdPath))
        return null;
    const content = fs.readFileSync(skillMdPath, 'utf-8');
    const lines = content.split('\n');
    if (lines[0] !== '---')
        return null;
    const endIndex = lines.slice(1).findIndex((line) => line === '---');
    if (endIndex < 0)
        return null;
    try {
        const frontmatter = lines.slice(1, endIndex + 1).join('\n');
        const parsed = yaml.parse(frontmatter);
        return typeof parsed?.[COMMAND_SKILL_MARKER] === 'string' ? parsed[COMMAND_SKILL_MARKER] : null;
    }
    catch {
        return null;
    }
}
export function shouldInstallCommandAsSkill(agent, version) {
    return !supports(agent, 'commands', version).ok && supports(agent, 'skills', version).ok;
}
/**
 * Agents whose native command files serve a separate surface while their CLI
 * consumes the generated skill form. Keep this registry distinct from
 * `shouldInstallCommandAsSkill`: these targets need both writes, not a format
 * replacement.
 */
export const COMMAND_SKILL_DUAL_WRITE_TARGETS = {
    cursor: true,
};
export function shouldAlsoInstallCommandAsSkill(agent, version) {
    return COMMAND_SKILL_DUAL_WRITE_TARGETS[agent] === true
        && supports(agent, 'commands', version).ok
        && supports(agent, 'skills', version).ok;
}
export function commandSkillName(commandName) {
    return commandName;
}
export function buildCommandSkillContent(commandName, sourcePath) {
    const { description, body } = readCommandMetadata(sourcePath);
    const skillDescription = description || `Slash command converted from /${commandName}`;
    return [
        '---',
        `name: ${JSON.stringify(commandSkillName(commandName))}`,
        `description: ${JSON.stringify(skillDescription)}`,
        `${COMMAND_SKILL_MARKER}: ${JSON.stringify(commandName)}`,
        '---',
        '',
        `# /${commandName}`,
        '',
        `This skill contains the behavior from the legacy \`/${commandName}\` slash command.`,
        'When invoked with `$' + commandSkillName(commandName) + '`, treat the text after the skill name as the original command arguments.',
        '',
        body.trimEnd(),
        '',
    ].join('\n');
}
function findSkillSourceDir(skillName, skillSourceDirs) {
    for (const dir of skillSourceDirs) {
        if (!dir)
            continue;
        const candidate = path.join(dir, skillName);
        if (fs.existsSync(candidate) && fs.lstatSync(candidate).isDirectory()) {
            return candidate;
        }
    }
    return null;
}
export function skillSourceExists(skillName, skillSourceDirs) {
    return findSkillSourceDir(skillName, skillSourceDirs) !== null;
}
export function readSkillSourceCommandMarker(skillName, skillSourceDirs) {
    const sourceDir = findSkillSourceDir(skillName, skillSourceDirs);
    if (!sourceDir)
        return null;
    return readSkillCommandMarker(path.join(sourceDir, 'SKILL.md'));
}
export function installCommandSkillToVersion(agentDir, commandName, sourcePath, skillSourceDirs = []) {
    const skillName = commandSkillName(commandName);
    const existingSkillSource = findSkillSourceDir(skillName, skillSourceDirs);
    if (existingSkillSource) {
        const sourceMarker = readSkillCommandMarker(path.join(existingSkillSource, 'SKILL.md'));
        if (sourceMarker !== commandName) {
            return { success: true, skipped: true, error: `Skill '${skillName}' already exists` };
        }
    }
    const skillsDir = safeJoin(agentDir, 'skills');
    const skillDir = safeJoin(skillsDir, skillName);
    try {
        fs.rmSync(skillDir, { recursive: true, force: true });
        fs.mkdirSync(skillDir, { recursive: true });
        fs.writeFileSync(safeJoin(skillDir, 'SKILL.md'), buildCommandSkillContent(commandName, sourcePath), 'utf-8');
        return { success: true };
    }
    catch (err) {
        return { success: false, error: err.message };
    }
}
export function listCommandSkillsInVersion(agentDir) {
    const skillsDir = path.join(agentDir, 'skills');
    if (!fs.existsSync(skillsDir))
        return [];
    const names = [];
    for (const entry of fs.readdirSync(skillsDir, { withFileTypes: true })) {
        if (!entry.isDirectory() || entry.name.startsWith('.'))
            continue;
        const marker = readSkillCommandMarker(path.join(skillsDir, entry.name, 'SKILL.md'));
        if (marker)
            names.push(marker);
    }
    return names.sort();
}
export function commandSkillMatches(agentDir, commandName, sourcePath) {
    const skillMdPath = path.join(agentDir, 'skills', commandSkillName(commandName), 'SKILL.md');
    if (!fs.existsSync(skillMdPath))
        return false;
    try {
        return fs.readFileSync(skillMdPath, 'utf-8') === buildCommandSkillContent(commandName, sourcePath);
    }
    catch {
        return false;
    }
}
export function removeCommandSkillFromVersion(agentDir, commandName) {
    const skillDir = path.join(agentDir, 'skills', commandSkillName(commandName));
    const skillMdPath = path.join(skillDir, 'SKILL.md');
    if (readSkillCommandMarker(skillMdPath) !== commandName) {
        return { success: true };
    }
    try {
        fs.rmSync(skillDir, { recursive: true, force: true });
        return { success: true };
    }
    catch (err) {
        return { success: false, error: err.message };
    }
}
