import fs from 'fs-extra';
import path from 'node:path';
import stripJsonComments from 'strip-json-comments';
/**
 * Finds and parses tsconfig files in the given directory and its parent directories.
 */
export async function findTsConfigPaths(configPath, logger, phase, transformTsConfigPathMappings) {
    let currentDir = path.dirname(configPath);
    while (currentDir !== path.parse(currentDir).root) {
        try {
            const files = await fs.readdir(currentDir);
            const tsConfigFiles = files.filter(file => /^tsconfig(\..*)?\.json$/.test(file));
            for (const fileName of tsConfigFiles) {
                const tsConfigFilePath = path.join(currentDir, fileName);
                try {
                    const { paths, baseUrl } = await getCompilerOptionsFromFile(tsConfigFilePath);
                    if (paths) {
                        const tsConfigBaseUrl = path.resolve(currentDir, baseUrl || '.');
                        const pathMappings = getTransformedPathMappings(paths, phase, transformTsConfigPathMappings);
                        return { baseUrl: tsConfigBaseUrl, paths: pathMappings };
                    }
                }
                catch (e) {
                    logger.warn(`Could not read or parse tsconfig file ${tsConfigFilePath}: ${e instanceof Error ? e.message : String(e)}`);
                }
            }
        }
        catch (e) {
            logger.warn(`Could not read directory ${currentDir}: ${e instanceof Error ? e.message : String(e)}`);
        }
        currentDir = path.dirname(currentDir);
    }
    return undefined;
}
async function getCompilerOptionsFromFile(tsConfigFilePath) {
    const tsConfigContent = await fs.readFile(tsConfigFilePath, 'utf-8');
    const tsConfig = JSON.parse(stripJsonComments(tsConfigContent));
    return tsConfig.compilerOptions || {};
}
function getTransformedPathMappings(paths, phase, transformTsConfigPathMappings) {
    const pathMappings = {};
    for (const [alias, patterns] of Object.entries(paths)) {
        const normalizedPatterns = patterns.map(pattern => pattern.replace(/\\/g, '/'));
        pathMappings[alias] = transformTsConfigPathMappings({
            phase,
            alias,
            patterns: normalizedPatterns,
        });
    }
    return pathMappings;
}
