import fs from "node:fs";
import { dirname, resolve } from "node:path";
import { nodeNormalizePath } from "../../utilities/node-normalize-path.js";
export function isPathWithinDirectories(path, directories) {
    const normalizedPath = nodeNormalizePath(path);
    for (const directory of directories) {
        const normalizedDirectory = nodeNormalizePath(directory);
        if (normalizedPath === normalizedDirectory ||
            normalizedPath.startsWith(`${normalizedDirectory}/`)) {
            return true;
        }
    }
    return false;
}
export function getWatchTargets(files, options = {}) {
    const baseDir = options.baseDir ?? process.cwd();
    const outdirPath = options.outdir
        ? nodeNormalizePath(resolve(baseDir, options.outdir))
        : undefined;
    const ignoreCache = options.ignoreCache ?? true;
    const includeDirectories = options.includeDirectories ?? true;
    const ignorePath = options.ignorePath;
    const isIgnoredPath = (path) => {
        const normalizedPath = nodeNormalizePath(path);
        // match whole path segments only — a project under e.g. /cachet-app/
        // must not have its inputs ignored
        if (ignoreCache && /(^|\/)cache(\/|$)/.test(normalizedPath)) {
            return true;
        }
        if (outdirPath &&
            (normalizedPath === outdirPath ||
                normalizedPath.startsWith(`${outdirPath}/`))) {
            return true;
        }
        return ignorePath ? ignorePath(normalizedPath) : false;
    };
    const nextFiles = new Set();
    const nextDirectories = new Set();
    for (const filePath of files) {
        const normalizedPath = nodeNormalizePath(filePath);
        if (isIgnoredPath(normalizedPath)) {
            continue;
        }
        nextFiles.add(normalizedPath);
        if (includeDirectories) {
            const directoryPath = dirname(normalizedPath);
            if (!isIgnoredPath(directoryPath)) {
                nextDirectories.add(directoryPath);
            }
        }
    }
    return {
        files: nextFiles,
        directories: nextDirectories,
        isIgnoredPath,
    };
}
export function createTrackedFs(options = {}) {
    const baseDir = options.baseDir ?? process.cwd();
    const baseFs = options.fs ?? fs;
    const readFiles = new Set();
    const trackRead = (path) => {
        readFiles.add(nodeNormalizePath(resolve(baseDir, path.toString())));
    };
    const wrappedFs = {
        ...baseFs,
        // @ts-expect-error - Node's fs has too many overloads
        readFile: (path, options, callback) => {
            trackRead(path);
            return baseFs.readFile(path, options, callback);
        },
        // @ts-expect-error - Node's fs has too many overloads
        readFileSync: (path, options) => {
            trackRead(path);
            return baseFs.readFileSync(path, options);
        },
        promises: {
            ...baseFs.promises,
            // @ts-expect-error - Node's fs.promises has too many overloads
            readFile: async (path, options) => {
                trackRead(path);
                return baseFs.promises.readFile(path, options);
            },
        },
    };
    return {
        fs: wrappedFs,
        readFiles,
        clearReadFiles: () => {
            readFiles.clear();
        },
    };
}
//# sourceMappingURL=tracked-fs.js.map