"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.qValueMatcher = exports.qConcatExpr = exports.qTemplateString = exports.qPropertyAccessIdentifier = exports.qVariableAccessIdentifier = exports.qVariableAssignmentIdentifier = exports.qStringValueAsSymbol = exports.qStringValue = exports.interpolateString = exports.coalesceVariable = exports.stripReservedPrefixFromKeyTokens = exports.cleanupTempVars = exports.loadFromTokenMap = exports.storeInTokenMap = exports.storeVarToken = exports.ANNOYING_METHODS = exports.GRADLE_PLUGINS = exports.REGISTRY_URLS = void 0;
const good_enough_parser_1 = require("good-enough-parser");
const regex_1 = require("../../../../util/regex");
exports.REGISTRY_URLS = {
    google: 'https://dl.google.com/android/maven2/',
    gradlePluginPortal: 'https://plugins.gradle.org/m2/',
    jcenter: 'https://jcenter.bintray.com/',
    mavenCentral: 'https://repo.maven.apache.org/maven2',
};
exports.GRADLE_PLUGINS = {
    checkstyle: 'com.puppycrawl.tools:checkstyle',
    codenarc: 'org.codenarc:CodeNarc',
    detekt: 'io.gitlab.arturbosch.detekt:detekt-core',
    findbugs: 'com.google.code.findbugs:findbugs',
    googleJavaFormat: 'com.google.googlejavaformat:google-java-format',
    jacoco: 'org.jacoco:jacoco',
    lombok: 'org.projectlombok:lombok',
    pmd: 'net.sourceforge.pmd:pmd-java',
    spotbugs: 'com.github.spotbugs:spotbugs',
};
exports.ANNOYING_METHODS = new Set([
    'createXmlValueRemover',
    'events',
    'args',
    'arrayOf',
    'listOf',
    'mutableListOf',
    'setOf',
    'mutableSetOf',
    'stages',
    'mapScalar', // https://github.com/apollographql/apollo-kotlin
]);
function storeVarToken(ctx, node) {
    ctx.varTokens.push(node);
    return ctx;
}
exports.storeVarToken = storeVarToken;
function storeInTokenMap(ctx, tokenMapKey) {
    ctx.tokenMap[tokenMapKey] = ctx.varTokens;
    ctx.varTokens = [];
    return ctx;
}
exports.storeInTokenMap = storeInTokenMap;
function loadFromTokenMap(ctx, tokenMapKey) {
    const tokens = ctx.tokenMap[tokenMapKey];
    if (!tokens) {
        throw new Error(`Expected token ${tokenMapKey} not found`);
    }
    return tokens;
}
exports.loadFromTokenMap = loadFromTokenMap;
function cleanupTempVars(ctx) {
    ctx.tokenMap = {};
    ctx.varTokens = [];
    return ctx;
}
exports.cleanupTempVars = cleanupTempVars;
function stripReservedPrefixFromKeyTokens(ctx) {
    const unwantedPrefixes = ['ext', 'extra', 'project', 'rootProject'];
    while (ctx.varTokens.length > 1 && // ensures there will be always at least one token
        ctx.varTokens[0] &&
        unwantedPrefixes.includes(ctx.varTokens[0].value)) {
        ctx.varTokens.shift();
    }
    return ctx;
}
exports.stripReservedPrefixFromKeyTokens = stripReservedPrefixFromKeyTokens;
function coalesceVariable(ctx) {
    if (ctx.varTokens.length > 1) {
        ctx.varTokens[0].value = ctx.varTokens
            .map((token) => token.value)
            .join('.');
        ctx.varTokens.length = 1;
    }
    return ctx;
}
exports.coalesceVariable = coalesceVariable;
function interpolateString(childTokens, variables) {
    const resolvedSubstrings = [];
    for (const childToken of childTokens) {
        const type = childToken.type;
        if (type === 'string-value') {
            resolvedSubstrings.push(childToken.value);
        }
        else if (type === 'symbol') {
            const varData = variables[childToken.value];
            if (varData) {
                resolvedSubstrings.push(varData.value);
            }
            else {
                return null;
            }
        }
        else {
            return null;
        }
    }
    return resolvedSubstrings.join('');
}
exports.interpolateString = interpolateString;
exports.qStringValue = good_enough_parser_1.query.str((ctx, node) => {
    storeVarToken(ctx, node);
    return ctx;
});
exports.qStringValueAsSymbol = good_enough_parser_1.query.str((ctx, node) => {
    const nodeTransformed = {
        ...node,
        type: 'symbol',
    };
    storeVarToken(ctx, nodeTransformed);
    return ctx;
});
// foo.bar["baz"] = "1.2.3"
exports.qVariableAssignmentIdentifier = good_enough_parser_1.query
    .sym(storeVarToken)
    .many(good_enough_parser_1.query.alt(good_enough_parser_1.query.op('.').sym(storeVarToken), good_enough_parser_1.query.tree({
    type: 'wrapped-tree',
    maxDepth: 1,
    startsWith: '[',
    endsWith: ']',
    search: good_enough_parser_1.query.begin().join(exports.qStringValueAsSymbol).end(),
})), 0, 32)
    .handler(stripReservedPrefixFromKeyTokens);
// foo.bar["baz"] -> "foo.bar.baz"
exports.qVariableAccessIdentifier = good_enough_parser_1.query
    .handler((ctx) => {
    ctx.tmpTokenStore.backupVarAccessTokens = ctx.varTokens;
    ctx.varTokens = [];
    return ctx;
})
    .join(exports.qVariableAssignmentIdentifier)
    .handler(coalesceVariable)
    .handler((ctx) => {
    ctx.varTokens = [
        ...ctx.tmpTokenStore.backupVarAccessTokens,
        ...ctx.varTokens,
    ];
    delete ctx.tmpTokenStore.backupVarAccessTokens;
    return ctx;
});
// project.ext.getProperty(...)
// extra.get(...)
exports.qPropertyAccessIdentifier = good_enough_parser_1.query
    .opt(good_enough_parser_1.query.sym((0, regex_1.regEx)(/^(?:rootProject|project)$/)).op('.'))
    .alt(good_enough_parser_1.query.opt(good_enough_parser_1.query.sym('ext').op('.')).sym((0, regex_1.regEx)(/^(?:property|getProperty)$/)), good_enough_parser_1.query
    .sym((0, regex_1.regEx)(/^(?:extra|ext)$/))
    .op('.')
    .sym('get'))
    .tree({
    maxDepth: 1,
    startsWith: '(',
    endsWith: ')',
    search: good_enough_parser_1.query.begin().join(exports.qStringValueAsSymbol).end(),
})
    .opt(good_enough_parser_1.query.sym('as').sym('String'));
// "foo${bar}baz"
exports.qTemplateString = good_enough_parser_1.query
    .tree({
    type: 'string-tree',
    maxDepth: 2,
    preHandler: (ctx) => {
        ctx.tmpTokenStore.templateTokens = [];
        return ctx;
    },
    search: good_enough_parser_1.query.alt(exports.qStringValue.handler((ctx) => {
        ctx.tmpTokenStore.templateTokens?.push(...ctx.varTokens);
        ctx.varTokens = [];
        return ctx;
    }), exports.qPropertyAccessIdentifier.handler((ctx) => {
        ctx.tmpTokenStore.templateTokens?.push(...ctx.varTokens);
        ctx.varTokens = [];
        return ctx;
    }), exports.qVariableAccessIdentifier.handler((ctx) => {
        ctx.tmpTokenStore.templateTokens?.push(...ctx.varTokens);
        ctx.varTokens = [];
        return ctx;
    })),
})
    .handler((ctx) => {
    ctx.varTokens = ctx.tmpTokenStore.templateTokens;
    return ctx;
});
// foo = "bar"
// foo + foo + "${foo}" + "foo" => "barbarbarfoo"
const qConcatExpr = (...matchers) => good_enough_parser_1.query.alt(...matchers).many(good_enough_parser_1.query.op('+').alt(...matchers), 0, 32);
exports.qConcatExpr = qConcatExpr;
exports.qValueMatcher = (0, exports.qConcatExpr)(exports.qTemplateString, exports.qPropertyAccessIdentifier, exports.qVariableAccessIdentifier);
//# sourceMappingURL=common.js.map