"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTouchedProjectsFromTsConfig = void 0;
const json_diff_1 = require("../../../../utils/json-diff");
const typescript_1 = require("../../utils/typescript");
const getTouchedProjectsFromTsConfig = (touchedFiles, _a, _b, _c, graph) => {
    const rootTsConfig = (0, typescript_1.getRootTsConfigFileName)();
    if (!rootTsConfig) {
        return [];
    }
    const tsConfigJsonChanges = touchedFiles.find((change) => change.file === rootTsConfig);
    if (!tsConfigJsonChanges) {
        return [];
    }
    const changes = tsConfigJsonChanges.getChanges();
    if (!allChangesArePathChanges(changes)) {
        return Object.keys(graph.nodes);
    }
    const touched = [];
    for (let i = 0; i < changes.length; i++) {
        const change = changes[i];
        if (change.path.length !== 4) {
            continue;
        }
        // If a path is deleted, everything is touched
        if (change.type === json_diff_1.JsonDiffType.Deleted) {
            return Object.keys(graph.nodes);
        }
        touched.push(...getProjectsAffectedByPaths(change, Object.values(graph.nodes)));
    }
    return touched;
};
exports.getTouchedProjectsFromTsConfig = getTouchedProjectsFromTsConfig;
function allChangesArePathChanges(changes) {
    return changes.every(isChangeToPathMappings);
}
/**
 * Gets both previous project and current project of a particular change to tsconfig paths
 */
function getProjectsAffectedByPaths(change, nodes) {
    const result = [];
    const paths = [change.value.lhs, change.value.rhs];
    paths.forEach((path) => {
        nodes.forEach((project) => {
            const normalizedPath = path && path.startsWith('./') ? path.substring(2) : path;
            const r = project.data.root;
            const root = r && r.endsWith('/') ? r.substring(0, r.length - 1) : r;
            if ((normalizedPath && root && normalizedPath.startsWith(root)) ||
                normalizedPath == root) {
                result.push(project.name);
            }
        });
    });
    return result;
}
/**
 * Change is possibly a change to path mappings
 */
function isChangeToPathMappings(change) {
    return ((0, json_diff_1.isJsonChange)(change) &&
        change.path[0] === 'compilerOptions' &&
        (!change.path[1] || change.path[1] === 'paths'));
}
