
import fs from 'fs-extra';
import path from 'path';

/**
 * Recursively copies a directory or file using streams to avoid 'copyfile' syscall issues (EINVAL)
 * on some cross-volume operations.
 */
export async function copyDirRecursive(src: string, dest: string) {
    const stats = await fs.stat(src);

    if (stats.isDirectory()) {
        await fs.ensureDir(dest);
        const files = await fs.readdir(src);

        await Promise.all(files.map(async (file) => {
            const srcPath = path.join(src, file);
            const destPath = path.join(dest, file);
            await copyDirRecursive(srcPath, destPath);
        }));
    } else {
        await copyFileStream(src, dest);
    }
}

async function copyFileStream(src: string, dest: string) {
    return new Promise<void>((resolve, reject) => {
        const readStream = fs.createReadStream(src);
        const writeStream = fs.createWriteStream(dest);

        readStream.on('error', reject);
        writeStream.on('error', reject);
        writeStream.on('finish', resolve);

        readStream.pipe(writeStream);
    });
}
