"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleApplyFrom = exports.handleLibraryDep = exports.handleCustomRegistryUrl = exports.handlePredefinedRegistryUrl = exports.handlePlugin = exports.handleLongFormDep = exports.handleDepInterpolation = exports.handleDepSimpleString = exports.handleAssignment = void 0;
const tslib_1 = require("tslib");
const url_1 = tslib_1.__importDefault(require("url"));
const upath_1 = tslib_1.__importDefault(require("upath"));
const logger_1 = require("../../../../logger");
const fs_1 = require("../../../../util/fs");
const regex_1 = require("../../../../util/regex");
const parser_1 = require("../parser");
const utils_1 = require("../utils");
const common_1 = require("./common");
function handleAssignment(ctx) {
    const key = (0, common_1.loadFromTokenMap)(ctx, 'keyToken')[0].value;
    const valTokens = (0, common_1.loadFromTokenMap)(ctx, 'valToken');
    if (valTokens.length > 1) {
        // = template string with multiple variables
        ctx.tokenMap.templateStringTokens = valTokens;
        handleDepInterpolation(ctx);
        delete ctx.tokenMap.templateStringTokens;
    }
    else {
        // = string value
        const dep = (0, utils_1.parseDependencyString)(valTokens[0].value);
        if (dep) {
            dep.groupName = key;
            dep.managerData = {
                fileReplacePosition: valTokens[0].offset + dep.depName.length + 1,
                packageFile: ctx.packageFile,
            };
            ctx.deps.push(dep);
        }
        const varData = {
            key,
            value: valTokens[0].value,
            fileReplacePosition: valTokens[0].offset,
            packageFile: ctx.packageFile,
        };
        ctx.globalVars[key] = varData;
    }
    return ctx;
}
exports.handleAssignment = handleAssignment;
function handleDepSimpleString(ctx) {
    const stringToken = (0, common_1.loadFromTokenMap)(ctx, 'stringToken')[0];
    const dep = (0, utils_1.parseDependencyString)(stringToken.value);
    if (dep) {
        dep.managerData = {
            fileReplacePosition: stringToken.offset + dep.depName.length + 1,
            packageFile: ctx.packageFile,
        };
        ctx.deps.push(dep);
    }
    return ctx;
}
exports.handleDepSimpleString = handleDepSimpleString;
function handleDepInterpolation(ctx) {
    const stringTokens = (0, common_1.loadFromTokenMap)(ctx, 'templateStringTokens');
    const templateString = (0, common_1.interpolateString)(stringTokens, ctx.globalVars);
    if (!templateString) {
        return ctx;
    }
    const dep = (0, utils_1.parseDependencyString)(templateString);
    if (!dep) {
        return ctx;
    }
    let packageFile;
    let fileReplacePosition;
    for (const token of stringTokens) {
        const varData = ctx.globalVars[token.value];
        if (token.type === 'symbol' && varData) {
            packageFile = varData.packageFile;
            fileReplacePosition = varData.fileReplacePosition;
            if (varData.value === dep.currentValue) {
                dep.managerData = { fileReplacePosition, packageFile };
                dep.groupName = varData.key;
            }
        }
    }
    if (!dep.managerData) {
        const lastToken = stringTokens[stringTokens.length - 1];
        if (lastToken?.type === 'string-value' &&
            dep.currentValue &&
            lastToken.value.startsWith(`:${dep.currentValue}`)) {
            packageFile = ctx.packageFile;
            fileReplacePosition = lastToken.offset + 1;
            delete dep.groupName;
        }
        else {
            dep.skipReason = 'contains-variable';
        }
        dep.managerData = { fileReplacePosition, packageFile };
    }
    ctx.deps.push(dep);
    return ctx;
}
exports.handleDepInterpolation = handleDepInterpolation;
function handleLongFormDep(ctx) {
    const groupIdTokens = (0, common_1.loadFromTokenMap)(ctx, 'groupId');
    const artifactIdTokens = (0, common_1.loadFromTokenMap)(ctx, 'artifactId');
    const versionTokens = (0, common_1.loadFromTokenMap)(ctx, 'version');
    const groupId = (0, common_1.interpolateString)(groupIdTokens, ctx.globalVars);
    const artifactId = (0, common_1.interpolateString)(artifactIdTokens, ctx.globalVars);
    const version = (0, common_1.interpolateString)(versionTokens, ctx.globalVars);
    if (!groupId || !artifactId || !version) {
        return ctx;
    }
    const dep = (0, utils_1.parseDependencyString)([groupId, artifactId, version].join(':'));
    if (!dep) {
        return ctx;
    }
    const methodName = ctx.tokenMap.methodName ?? null;
    if (versionTokens.length > 1) {
        // = template string with multiple variables
        dep.skipReason = 'unknown-version';
    }
    else if (versionTokens[0].type === 'symbol') {
        const varData = ctx.globalVars[versionTokens[0].value];
        if (varData) {
            dep.groupName = varData.key;
            dep.managerData = {
                fileReplacePosition: varData.fileReplacePosition,
                packageFile: varData.packageFile,
            };
        }
    }
    else {
        // = string value
        dep.managerData = {
            fileReplacePosition: versionTokens[0].offset,
            packageFile: ctx.packageFile,
        };
    }
    if (methodName?.[0] && common_1.ANNOYING_METHODS.has(methodName[0].value)) {
        dep.skipReason = 'ignored';
    }
    ctx.deps.push(dep);
    return ctx;
}
exports.handleLongFormDep = handleLongFormDep;
function handlePlugin(ctx) {
    const methodName = (0, common_1.loadFromTokenMap)(ctx, 'methodName')[0];
    const pluginName = (0, common_1.loadFromTokenMap)(ctx, 'pluginName')[0];
    const pluginVersion = (0, common_1.loadFromTokenMap)(ctx, 'version');
    const plugin = pluginName.value;
    const depName = methodName.value === 'kotlin' ? `org.jetbrains.kotlin.${plugin}` : plugin;
    const packageName = `${depName}:${depName}.gradle.plugin`;
    const dep = {
        depType: 'plugin',
        depName,
        packageName,
        registryUrls: ['https://plugins.gradle.org/m2/'],
        commitMessageTopic: `plugin ${depName}`,
        currentValue: pluginVersion[0].value,
        managerData: {
            fileReplacePosition: pluginVersion[0].offset,
            packageFile: ctx.packageFile,
        },
    };
    if (pluginVersion.length > 1) {
        // = template string with multiple variables
        dep.skipReason = 'unknown-version';
    }
    else if (pluginVersion[0].type === 'symbol') {
        const varData = ctx.globalVars[pluginVersion[0].value];
        if (varData) {
            dep.currentValue = varData.value;
            dep.managerData = {
                fileReplacePosition: varData.fileReplacePosition,
                packageFile: varData.packageFile,
            };
        }
        else {
            dep.skipReason = 'unknown-version';
        }
    }
    ctx.deps.push(dep);
    return ctx;
}
exports.handlePlugin = handlePlugin;
function handlePredefinedRegistryUrl(ctx) {
    const registryName = (0, common_1.loadFromTokenMap)(ctx, 'registryUrl')[0].value;
    ctx.depRegistryUrls.push(common_1.REGISTRY_URLS[registryName]);
    return ctx;
}
exports.handlePredefinedRegistryUrl = handlePredefinedRegistryUrl;
function handleCustomRegistryUrl(ctx) {
    let localVariables = ctx.globalVars;
    if (ctx.tokenMap.name) {
        const nameTokens = (0, common_1.loadFromTokenMap)(ctx, 'name');
        const nameValue = (0, common_1.interpolateString)(nameTokens, localVariables);
        if (nameValue) {
            localVariables = {
                ...localVariables,
                name: {
                    key: 'name',
                    value: nameValue,
                },
            };
        }
    }
    let registryUrl = (0, common_1.interpolateString)((0, common_1.loadFromTokenMap)(ctx, 'registryUrl'), localVariables);
    if (registryUrl) {
        registryUrl = registryUrl.replace((0, regex_1.regEx)(/\\/g), '');
        try {
            const { host, protocol } = url_1.default.parse(registryUrl);
            if (host && protocol) {
                ctx.depRegistryUrls.push(registryUrl);
            }
        }
        catch (e) {
            // no-op
        }
    }
    return ctx;
}
exports.handleCustomRegistryUrl = handleCustomRegistryUrl;
function handleLibraryDep(ctx) {
    const groupIdTokens = (0, common_1.loadFromTokenMap)(ctx, 'groupId');
    const artifactIdTokens = (0, common_1.loadFromTokenMap)(ctx, 'artifactId');
    const groupId = (0, common_1.interpolateString)(groupIdTokens, ctx.globalVars);
    const artifactId = (0, common_1.interpolateString)(artifactIdTokens, ctx.globalVars);
    if (!groupId || !artifactId) {
        return ctx;
    }
    const aliasToken = (0, common_1.loadFromTokenMap)(ctx, 'alias')[0];
    const key = `libs.${aliasToken.value.replace((0, regex_1.regEx)(/[-_]/g), '.')}`;
    const varData = {
        key,
        value: `${groupId}:${artifactId}`,
        fileReplacePosition: aliasToken.offset,
        packageFile: ctx.packageFile,
    };
    ctx.globalVars = { ...ctx.globalVars, [key]: varData };
    if (ctx.tokenMap.version) {
        const version = (0, common_1.interpolateString)((0, common_1.loadFromTokenMap)(ctx, 'version'), ctx.globalVars);
        if (version) {
            handleLongFormDep(ctx);
        }
    }
    return ctx;
}
exports.handleLibraryDep = handleLibraryDep;
function handleApplyFrom(ctx) {
    let scriptFile = (0, common_1.interpolateString)((0, common_1.loadFromTokenMap)(ctx, 'scriptFile'), ctx.globalVars);
    if (!scriptFile) {
        return ctx;
    }
    if (ctx.tokenMap.parentPath) {
        const parentPath = (0, common_1.interpolateString)((0, common_1.loadFromTokenMap)(ctx, 'parentPath'), ctx.globalVars);
        if (parentPath && scriptFile) {
            scriptFile = upath_1.default.join(parentPath, scriptFile);
        }
    }
    if (ctx.recursionDepth > 2) {
        logger_1.logger.debug(`Max recursion depth reached in script file: ${scriptFile}`);
        return ctx;
    }
    if (!(0, regex_1.regEx)(/\.gradle(\.kts)?$/).test(scriptFile)) {
        logger_1.logger.warn({ scriptFile }, `Only Gradle files can be included`);
        return ctx;
    }
    const scriptFilePath = (0, fs_1.getSiblingFileName)(ctx.packageFile, scriptFile);
    if (!ctx.fileContents[scriptFilePath]) {
        logger_1.logger.debug(`Failed to process included Gradle file ${scriptFilePath}`);
        return ctx;
    }
    const matchResult = (0, parser_1.parseGradle)(
    // TODO #7154
    ctx.fileContents[scriptFilePath], ctx.globalVars, scriptFilePath, ctx.fileContents, ctx.recursionDepth + 1);
    ctx.deps.push(...matchResult.deps);
    ctx.globalVars = { ...ctx.globalVars, ...matchResult.vars };
    ctx.depRegistryUrls.push(...matchResult.urls);
    return ctx;
}
exports.handleApplyFrom = handleApplyFrom;
//# sourceMappingURL=handlers.js.map