import { promises as fs } from 'node:fs';
import path from 'node:path';
import { messages } from '../messages/index.js';
import { MIGRACAO_MAPA, TUTANUS_ARQUIVOS, TUTANUS_DIRS } from './paths.js';
async function fileExists(fileCaminho) {
    try {
        await fs.stat(fileCaminho);
        return true;
    }
    catch {
        return false;
    }
}
async function ensureDir(fileCaminho) {
    const dir = path.dirname(fileCaminho);
    await fs.mkdir(dir, {
        recursive: true
    });
}
async function tryMigrate(targetPath) {
    const legacyCaminho = Object.entries(MIGRACAO_MAPA).find(([_, target]) => target === targetPath)?.[0];
    if (!legacyCaminho) {
        return {
            migrated: false
        };
    }
    try {
        const content = await fs.readFile(legacyCaminho, 'utf-8');
        await ensureDir(targetPath);
        try {
            await fs.writeFile(targetPath, content, { encoding: 'utf-8', flag: 'wx' });
        }
        catch (err) {
            const code = err.code;
            if (code === 'EEXIST') {
                return {
                    migrated: true,
                    from: legacyCaminho,
                    to: targetPath
                };
            }
            throw err;
        }
        const backupCaminho = `${legacyCaminho}.migrated`;
        await fs.rename(legacyCaminho, backupCaminho).catch(() => {
        });
        messages.log.info(`Migração automática: ${path.basename(legacyCaminho)} → ${path.basename(targetPath)}`);
        return {
            migrated: true,
            from: legacyCaminho,
            to: targetPath
        };
    }
    catch (erro) {
        const code = erro.code;
        if (code === 'ENOENT') {
            return {
                migrated: false
            };
        }
        messages.log.aviso(`Falha na migração de ${legacyCaminho}: ${erro.message}`);
        return {
            migrated: false
        };
    }
}
export async function readJSON(fileCaminho, options = {}) {
    const { default: defaultValue, migrate = true, validate } = options;
    try {
        if (migrate) {
            const migration = await tryMigrate(fileCaminho);
            if (migration.migrated && migration.to) {
                fileCaminho = migration.to;
            }
        }
        const content = await fs.readFile(fileCaminho, 'utf-8');
        const parsed = JSON.parse(content);
        if (validate && !validate(parsed)) {
            throw new Error(messages.ExcecoesMensagens.validacaoFalhouPara(String(fileCaminho)));
        }
        return parsed;
    }
    catch (erro) {
        const code = erro.code;
        if (code === 'ENOENT' && defaultValue !== undefined) {
            return defaultValue;
        }
        if (defaultValue !== undefined) {
            return defaultValue;
        }
        if (code === 'ENOENT') {
            throw new Error(messages.ExcecoesMensagens.arquivoNaoEncontrado(String(fileCaminho)));
        }
        throw new Error(messages.ExcecoesMensagens.erroAoLer(String(fileCaminho), erro.message));
    }
}
export async function writeJSON(fileCaminho, data, options = {}) {
    const { createDirs = true, backup = false, pretty = true } = options;
    try {
        if (createDirs) {
            await ensureDir(fileCaminho);
        }
        if (backup) {
            const backupCaminho = `${fileCaminho}.backup`;
            await fs.copyFile(fileCaminho, backupCaminho).catch(() => {
            });
        }
        const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
        await fs.writeFile(fileCaminho, content, 'utf-8');
    }
    catch (erro) {
        throw new Error(messages.ExcecoesMensagens.erroAoEscrever(String(fileCaminho), erro.message));
    }
}
export async function deleteJSON(fileCaminho, options = {}) {
    const { backup = true } = options;
    try {
        if (backup) {
            const backupCaminho = `${fileCaminho}.deleted`;
            await fs.rename(fileCaminho, backupCaminho);
        }
        else {
            await fs.unlink(fileCaminho);
        }
    }
    catch (erro) {
        const code = erro.code;
        if (code === 'ENOENT') {
            return;
        }
        throw new Error(messages.ExcecoesMensagens.erroAoDeletar(String(fileCaminho), erro.message));
    }
}
export async function listJSONFiles(dirPath) {
    try {
        const exists = await fileExists(dirPath);
        if (!exists) {
            return [];
        }
        const entries = await fs.readdir(dirPath, {
            withFileTypes: true
        });
        const jsonArquivos = entries.filter(entry => entry.isFile() && entry.name.endsWith('.json')).map(entry => path.join(dirPath, entry.name));
        return jsonArquivos;
    }
    catch (erro) {
        messages.log.aviso(`Erro ao listar arquivos em ${dirPath}: ${erro.message}`);
        return [];
    }
}
export const ArquivoRegistro = {
    read: readJSON,
    write: writeJSON,
    delete: deleteJSON,
    list: listJSONFiles,
    paths: TUTANUS_ARQUIVOS,
    dirs: TUTANUS_DIRS
};
//# sourceMappingURL=file-registry.js.map