"use strict";
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.VscGitEager = void 0;
exports.createVcsGitEagerConfig = createVcsGitEagerConfig;
const tslib_1 = require("tslib");
const node_path_1 = require("node:path");
const logger_1 = tslib_1.__importStar(require("@docusaurus/logger"));
const gitUtils_1 = require("./gitUtils");
// The Map keys should be absolute file paths, not relative Git paths
function resolveFileInfoMapPaths(repoRoot, filesInfo) {
    function transformMapEntry(entry) {
        // We just resolve the Git paths that are relative to the repo root
        return [(0, node_path_1.resolve)(repoRoot, entry[0]), entry[1]];
    }
    return new Map(Array.from(filesInfo.entries()).map(transformMapEntry));
}
function mergeFileMaps(fileMaps) {
    return new Map(fileMaps.flatMap((m) => [...m]));
}
async function loadAllGitFilesInfoMap(cwd) {
    const roots = await logger_1.PerfLogger.async('Reading Git root dirs', () => (0, gitUtils_1.getGitAllRepoRoots)(cwd));
    const allMaps = await Promise.all(roots.map(async (root) => {
        const map = await logger_1.PerfLogger.async(`Reading Git history for repo ${logger_1.default.path((0, node_path_1.basename)(root))}`, () => (0, gitUtils_1.getGitRepositoryFilesInfo)(root));
        return resolveFileInfoMapPaths(root, map);
    }));
    return mergeFileMaps(allMaps);
}
async function initialize({ siteDir, }) {
    try {
        const isInWorktree = await (0, gitUtils_1.isGitInsideWorktree)(siteDir);
        if (!isInWorktree) {
            return { type: 'error', reason: 'not-in-worktree' };
        }
        const filesMap = await loadAllGitFilesInfoMap(siteDir);
        return { type: 'success', filesMap };
    }
    catch (error) {
        return { type: 'error', reason: 'unknown', cause: error };
    }
}
function createVcsGitEagerConfig() {
    let initPromise = null;
    async function getGitFileInfo(filePath) {
        const init = (await initPromise);
        if (init.type === 'success') {
            return init.filesMap.get(filePath) ?? null;
        }
        else if (init.reason === 'not-in-worktree') {
            throw new Error(`This Docusaurus site is outside any Git worktree.
Unable to read Git info for file ${logger_1.default.path(filePath)} `);
        }
        else {
            throw init.cause;
        }
    }
    return {
        initialize: ({ siteDir }) => {
            if (initPromise) {
                // We only initialize this VCS once!
                // For i18n sites, this permits reading ahead of time for all locales
                // so that it only slows down the first locale
                // I assume this logic is fine, but we'll see if it causes trouble
                // Note: we could also only call "initialize()" once from the outside,
                // But maybe it could be useful for custom VCS implementations to be
                // able to initialize once per locale?
                logger_1.PerfLogger.log('Git Eager VCS strategy already initialized, skipping re-initialization');
                return;
            }
            initPromise = logger_1.PerfLogger.async('Git Eager VCS init', () => initialize({ siteDir }));
        },
        getFileCreationInfo: async (filePath) => {
            const fileInfo = await getGitFileInfo(filePath);
            return fileInfo?.creation ?? null;
        },
        getFileLastUpdateInfo: async (filePath) => {
            const fileInfo = await getGitFileInfo(filePath);
            return fileInfo?.lastUpdate ?? null;
        },
    };
}
// TODO it probably shouldn't be a singleton, but good enough for now
exports.VscGitEager = createVcsGitEagerConfig();
//# sourceMappingURL=vcsGitEager.js.map