import { readFileSync } from 'fs';
import logger from '../utils/objects/logger.js';
import * as parser from '../parsing/api.js';
import performJDLPostParsingTasks from '../parsing/jdl-post-parsing-tasks.js';
export function parseFromFiles(files, runtime) {
    checkFiles(files);
    checkAllTheFilesAreJDLFiles(files);
    return parse(getFilesContent(files), runtime);
}
export function parseFromContent(content, runtime) {
    if (!content) {
        throw new Error('A valid JDL content must be passed so as to be parsed.');
    }
    return parse(content, runtime);
}
export function getCstFromContent(content, runtime) {
    return getCst(content, runtime);
}
function checkFiles(files) {
    if (!files || files.length === 0) {
        throw new Error('The files must be passed to be parsed.');
    }
}
function getFilesContent(files) {
    try {
        return files.length === 1 ? readFileSync(files[0], 'utf-8') : aggregateFiles(files);
    }
    catch (error) {
        throw new Error(`The passed file '${files[0]}' must exist and must not be a directory to be read.`, { cause: error });
    }
}
function checkAllTheFilesAreJDLFiles(files) {
    for (let i = 0; i < files.length; i++) {
        checkFileIsJDLFile(files[i]);
    }
}
function parse(content, runtime) {
    if (!content) {
        throw new Error('File content must be passed, it is currently empty.');
    }
    try {
        const processedInput = filterJDLDirectives(removeInternalJDLComments(content));
        const parsedContent = parser.parse(processedInput, undefined, runtime);
        return performJDLPostParsingTasks(parsedContent);
    }
    catch (error) {
        if (error instanceof SyntaxError) {
            logger.error(`Syntax error message:\n\t${error.message}`);
        }
        throw error;
    }
}
function getCst(content, runtime) {
    if (!content) {
        throw new Error('File content must be passed, it is currently empty.');
    }
    try {
        const processedInput = filterJDLDirectives(removeInternalJDLComments(content));
        return parser.getCst(processedInput, undefined, runtime);
    }
    catch (error) {
        if (error instanceof SyntaxError) {
            logger.error(`Syntax error message:\n\t${error.message}`);
        }
        throw error;
    }
}
function removeInternalJDLComments(content) {
    return content.replace(/\/\/[^\n\r]*/gm, '');
}
function filterJDLDirectives(content) {
    return content.replace(/^\u0023.*/gm, '');
}
export function checkFileIsJDLFile(file) {
    if (!file.endsWith('.jh') && !file.endsWith('.jdl')) {
        throw new Error(`The passed file '${file}' must end with '.jh' or '.jdl' to be valid.`);
    }
}
function aggregateFiles(files) {
    return files.map(file => readFileSync(file, 'utf-8')).join('\n');
}
