/**
 * File Writer
 *
 * Writes generated files to disk with smart merge strategies.
 */
import { promises as fs } from 'fs';
import { join, dirname } from 'path';
import { pathExists, runWithLimit } from './async-utils.js';
/**
 * Clean and recreate output directory (used for testing only)
 */
const WRITE_CONCURRENCY = 16;
export async function cleanOutputDir(dir) {
    if (await pathExists(dir)) {
        await fs.rm(dir, { recursive: true, force: true });
    }
    await fs.mkdir(dir, { recursive: true });
}
/**
 * Write generated files to disk (overwrites all)
 */
export async function writeFiles(outputDir, files) {
    await runWithLimit(files, WRITE_CONCURRENCY, async (file) => {
        const fullPath = join(outputDir, file.path);
        const fileDir = dirname(fullPath);
        // Ensure directory exists
        await fs.mkdir(fileDir, { recursive: true });
        // Write file
        await fs.writeFile(fullPath, file.content, 'utf-8');
    });
}
/**
 * Write generated files with smart merge strategy
 *
 * - Generated code (src/, etc.): Overwrite
 * - Migrations (drizzle/, supabase/migrations/): Only add new files, don't overwrite
 * - package.json: Merge dependencies
 * - Config files: Overwrite
 */
export async function writeFilesWithMerge(outputDir, files) {
    await runWithLimit(files, WRITE_CONCURRENCY, async (file) => {
        const fullPath = join(outputDir, file.path);
        const fileDir = dirname(fullPath);
        // Ensure directory exists
        await fs.mkdir(fileDir, { recursive: true });
        // Check if this is a migration SQL file (don't overwrite existing SQL migrations)
        // Journal and snapshot JSON files in meta/ are always overwritten — they track current state
        const isMigrationSql = (file.path.includes('/migrations/') ||
            file.path.startsWith('drizzle/') ||
            file.path.startsWith('supabase/migrations/')) &&
            file.path.endsWith('.sql');
        if (isMigrationSql && await pathExists(fullPath)) {
            // Skip existing migration SQL files - don't overwrite
            return;
        }
        // Check if this is package.json
        if (file.path === 'package.json' && await pathExists(fullPath)) {
            // Merge package.json
            const merged = await mergePackageJson(fullPath, file.content);
            await fs.writeFile(fullPath, merged, 'utf-8');
            return;
        }
        // Default: write/overwrite
        await fs.writeFile(fullPath, file.content, 'utf-8');
    });
}
/**
 * Merge generated package.json with existing one
 * Preserves user's custom scripts, adds new dependencies
 */
async function mergePackageJson(existingPath, newContent) {
    try {
        const existing = JSON.parse(await fs.readFile(existingPath, 'utf-8'));
        const generated = JSON.parse(newContent);
        // Merge dependencies (generated takes precedence for versions)
        const merged = {
            ...generated,
            ...existing,
            name: generated.name || existing.name,
            version: existing.version || generated.version,
            scripts: {
                ...generated.scripts,
                ...existing.scripts, // User scripts take precedence
            },
            dependencies: {
                ...existing.dependencies,
                ...generated.dependencies, // Generated deps take precedence (newer versions)
            },
            devDependencies: {
                ...existing.devDependencies,
                ...generated.devDependencies,
            },
            peerDependencies: {
                ...existing.peerDependencies,
                ...generated.peerDependencies,
            },
            optionalDependencies: {
                ...existing.optionalDependencies,
                ...generated.optionalDependencies,
            },
            engines: {
                ...generated.engines,
                ...existing.engines,
            },
            packageManager: existing.packageManager ?? generated.packageManager,
        };
        return JSON.stringify(merged, null, 2);
    }
    catch {
        // If merge fails, use generated content
        return newContent;
    }
}
/**
 * Write a single file
 */
export async function writeFile(filePath, content) {
    const dir = dirname(filePath);
    await fs.mkdir(dir, { recursive: true });
    await fs.writeFile(filePath, content, 'utf-8');
}
//# sourceMappingURL=file-writer.js.map