import { VariableType } from './constants.js';
export function getPreserveTransformer({ body, authorizationHeader, }) {
    return function (input, prop, originalResult) {
        if (body) {
            // Keep original body without extra stringifying (assume that body already stringified)
            if (prop === 'body' && typeof input.body === 'string') {
                return input.body;
            }
        }
        if (authorizationHeader) {
            // Keep original Authorization header without stringifying (for basic auth code)
            if (prop === 'Authorization' && typeof input.Authorization === 'string') {
                return input.Authorization;
            }
        }
        return originalResult;
    };
}
export function addIndentation(str, { level = 0, indent = '  ', firstLine = true } = {}) {
    const indentation = indent.repeat(level);
    // TODO: keep original indentaion type
    const strWithExtraIndentation = str.replace(/(\r\n|\n|\r)/gm, `\n${indentation}`);
    if (firstLine) {
        return indentation.concat(strWithExtraIndentation);
    }
    return strWithExtraIndentation;
}
/**
 * Parse url with arguments into concatenation operands array so it can be manipulated easily language-independently
 *
 * @example
 * // returns [{type: 'string', value: '/var/'}, {type: 'variable', name: 'test'}, {type: "string", value: "/"}]
 * parseUrlIntoOperands("/url/:test/", {test: 1})
 **/
export function parseUrlIntoOperands(url, params) {
    const paramNames = Object.keys(params);
    const paramNamesInOrder = paramNames
        .map((name) => ({ name, idx: url.indexOf(`{${name}}`) }))
        .filter(({ idx }) => idx > -1) // filter out unused
        .sort((a, b) => a.idx - b.idx);
    const operands = [];
    let prevIdx = 0;
    for (const { name, idx } of paramNamesInOrder) {
        if (idx > prevIdx) {
            operands.push({ type: 'string', value: url.substring(prevIdx, idx) });
        }
        operands.push({ type: 'variable', name });
        prevIdx = idx + name.length + 2; // 2 for curly braces
    }
    if (prevIdx < url.length)
        operands.push({ type: 'string', value: url.substring(prevIdx) });
    return operands;
}
export function buildUrlExpression(source, code, url) {
    const { joinSymbol, variableWrapperFn, stringLiteral, urlFieldName, rawName } = code.langOptions;
    const { pathParameters = {}, serverVariables = {} } = source;
    const variablesData = { ...pathParameters, ...serverVariables };
    return parseUrlIntoOperands(url ?? source[urlFieldName] ?? '', variablesData)
        .map((operand) => {
        if (operand.type === 'variable') {
            const variableValue = variablesData[operand.name];
            const variableName = rawName ? operand.name : code.var(operand.name, VariableType.PATH);
            return variableWrapperFn(variableName, variableValue);
        }
        else {
            // string
            return stringLiteral(operand.value);
        }
    })
        .join(joinSymbol);
}
export function printUrlVariablesDeclarations(source, code, indentationLevel) {
    const variablesData = { ...source.pathParameters, ...source.serverVariables };
    Object.entries(variablesData).forEach(([key, value]) => {
        if (key === 'server')
            return; // special case for environment variable called server
        const variableValue = value || `YOUR_${key}_PARAMETER`;
        const variableName = code.var(key, VariableType.PATH);
        const operands = parseUrlIntoOperands(variableValue, variablesData);
        const hasVariableInterpolation = operands.some((operand) => operand.type === 'variable');
        const expression = buildUrlExpression(source, code, variableValue);
        if (indentationLevel !== undefined) {
            code.push(indentationLevel, code.langOptions.variableDeclaration(variableName, { hasVariableInterpolation }), expression);
        }
        else {
            code.push(code.langOptions.variableDeclaration(variableName, { hasVariableInterpolation }), expression);
        }
    });
}
//# sourceMappingURL=code-helpers.js.map