"use strict";
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.shouldStepBeLastStepInStepGroup = exports.isStepFirstStepInStepGroup = exports.isModulator = exports.isTraversalSource = void 0;
var types_1 = require("../../../types");
var consts_1 = require("../../../consts");
var recreateQueryOnelinerFromSyntaxTree_1 = require("../../../recreateQueryOnelinerFromSyntaxTree");
var isTraversalSource = function (step) {
    return step.type === types_1.TokenType.Word && step.word === 'g';
};
exports.isTraversalSource = isTraversalSource;
var isModulator = function (step) {
    if (step.type !== types_1.TokenType.Method && step.type !== types_1.TokenType.Closure)
        return false;
    if (step.method.type !== types_1.TokenType.Word)
        return false;
    return consts_1.STEP_MODULATORS.includes(step.method.word);
};
exports.isModulator = isModulator;
var isStepFirstStepInStepGroup = function (_a) {
    var stepsInStepGroup = _a.stepsInStepGroup;
    return !stepsInStepGroup.length;
};
exports.isStepFirstStepInStepGroup = isStepFirstStepInStepGroup;
var isLineTooLongWithSubsequentModulators = function (config) { return function (_a, step, index, steps) {
    var stepsInStepGroup = _a.stepsInStepGroup, stepGroups = _a.stepGroups;
    var stepsWithSubsequentModulators = steps.slice(index + 1).reduce(function (aggregator, step) {
        var stepsInStepGroup = aggregator.stepsInStepGroup, hasReachedFinalModulator = aggregator.hasReachedFinalModulator;
        if (hasReachedFinalModulator)
            return aggregator;
        if ((0, exports.isModulator)(step)) {
            return __assign(__assign({}, aggregator), { stepsInStepGroup: __spreadArray(__spreadArray([], stepsInStepGroup, true), [step], false) });
        }
        return __assign(__assign({}, aggregator), { hasReachedFinalModulator: true });
    }, {
        stepsInStepGroup: __spreadArray(__spreadArray([], stepsInStepGroup, true), [step], false),
        hasReachedFinalModulator: false,
    }).stepsInStepGroup;
    var stepGroupIndentationIncrease = (function () {
        var traversalSourceIndentationIncrease = stepGroups[0] && (0, exports.isTraversalSource)(stepGroups[0].steps[0]) ? 2 : 0;
        var modulatorIndentationIncrease = (0, exports.isModulator)(__spreadArray(__spreadArray([], stepsInStepGroup, true), [step], false)[0]) ? 2 : 0;
        var indentationIncrease = traversalSourceIndentationIncrease + modulatorIndentationIncrease;
        return indentationIncrease;
    })();
    var recreatedQueryWithSubsequentModulators = (0, recreateQueryOnelinerFromSyntaxTree_1.default)(config.localIndentation + stepGroupIndentationIncrease)({
        type: types_1.TokenType.Traversal,
        steps: stepsWithSubsequentModulators,
    });
    var lineIsTooLongWithSubsequentModulators = recreatedQueryWithSubsequentModulators.length > config.maxLineLength;
    return lineIsTooLongWithSubsequentModulators;
}; };
// If the first step in a group is a modulator, then it must also be the last step in the group
var shouldStepBeLastStepInStepGroup = function (config) { return function (_a, step, index, steps) {
    var stepsInStepGroup = _a.stepsInStepGroup, stepGroups = _a.stepGroups;
    var isFirstStepInStepGroup = !stepsInStepGroup.length;
    var isLastStep = index === steps.length - 1;
    var nextStepIsModulator = !isLastStep && (0, exports.isModulator)(steps[index + 1]);
    var lineIsTooLongWithSubsequentModulators = isLineTooLongWithSubsequentModulators(config)({ stepsInStepGroup: stepsInStepGroup, stepGroups: stepGroups }, step, index, steps);
    // If the first step in a group is a modulator, then it must also be the last step in the group
    var stepShouldBeLastStepInStepGroup = isLastStep ||
        (isFirstStepInStepGroup && (0, exports.isModulator)(step)) ||
        ((step.type === types_1.TokenType.Method || step.type === types_1.TokenType.Closure) &&
            !(nextStepIsModulator && !lineIsTooLongWithSubsequentModulators));
    return stepShouldBeLastStepInStepGroup;
}; };
exports.shouldStepBeLastStepInStepGroup = shouldStepBeLastStepInStepGroup;
