import { chmod, readdir, rm } from 'node:fs/promises';
import { join } from 'node:path';
import { compareVersions } from '../../../init/tools/shared/version.js';
import { getSkillVersion } from '../../../shared/frontmatter.js';
import { copyDirectory, copySingleFile, dirExists, fileExists } from '../../../../fs/io.js';
async function chmodFilesExecutable(directory) {
    const entries = await readdir(directory, { withFileTypes: true });
    for (const entry of entries) {
        const path = join(directory, entry.name);
        if (entry.isDirectory()) {
            await chmodFilesExecutable(path);
        }
        else if (entry.isFile()) {
            await chmod(path, 0o755);
        }
    }
}
async function ensureNestedScriptsExecutable(destination) {
    const scriptsDirectory = join(destination, 'scripts');
    if (await dirExists(scriptsDirectory)) {
        await chmodFilesExecutable(scriptsDirectory);
    }
}
export async function pathExists(path) {
    return (await fileExists(path)) || (await dirExists(path));
}
export async function copyDirWithStatus(source, destination, force) {
    const exists = await pathExists(destination);
    if (exists && !force) {
        return 'skipped';
    }
    if (exists && force) {
        await rm(destination, { recursive: true, force: true });
        await copyDirectory(source, destination);
        await ensureNestedScriptsExecutable(destination);
        return 'updated';
    }
    await copyDirectory(source, destination);
    await ensureNestedScriptsExecutable(destination);
    return 'copied';
}
export async function copyFileWithStatus(source, destination, force) {
    const exists = await pathExists(destination);
    if (exists && !force) {
        return 'skipped';
    }
    if (exists && force) {
        await rm(destination, { recursive: true, force: true });
        await copySingleFile(source, destination);
        return 'updated';
    }
    await copySingleFile(source, destination);
    return 'copied';
}
export async function copyDirWithVersionCheck(source, destination, force) {
    const exists = await pathExists(destination);
    if (!exists) {
        await copyDirectory(source, destination);
        await ensureNestedScriptsExecutable(destination);
        return { status: 'copied' };
    }
    if (force) {
        await rm(destination, { recursive: true, force: true });
        await copyDirectory(source, destination);
        await ensureNestedScriptsExecutable(destination);
        return { status: 'updated' };
    }
    const bundledVersion = await getSkillVersion(source);
    const installedVersion = await getSkillVersion(destination);
    const versionState = compareVersions(installedVersion, bundledVersion);
    if (versionState === 'outdated') {
        return { status: 'outdated', installedVersion, bundledVersion };
    }
    return { status: 'skipped' };
}
