"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 __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.formatMethod = void 0;
var recreateQueryOnelinerFromSyntaxTree_1 = require("../recreateQueryOnelinerFromSyntaxTree");
var types_1 = require("../types");
var utils_1 = require("../utils");
var utils_2 = require("./utils");
// Groups arguments into argument groups an adds a localIndentation property
var formatMethod = function (formatSyntaxTree) { return function (config) { return function (syntaxTree) {
    var recreatedQuery = (0, recreateQueryOnelinerFromSyntaxTree_1.default)(config.localIndentation)(syntaxTree);
    var method = formatSyntaxTree((0, utils_2.withNoEndDotInfo)(config))(syntaxTree.method);
    var argumentsWillNotBeWrapped = recreatedQuery.length <= config.maxLineLength;
    if (argumentsWillNotBeWrapped) {
        return {
            type: types_1.TokenType.Method,
            method: method,
            // The arguments property is here so that the resulted syntax tree can
            // still be understood by recreateQueryOnelinerFromSyntaxTree
            arguments: syntaxTree.arguments,
            argumentGroups: [
                syntaxTree.arguments.reduce(function (argumentGroup, syntaxTree) {
                    return __spreadArray(__spreadArray([], argumentGroup, true), [
                        formatSyntaxTree(
                        // Since the method's arguments will be on the same line, their horizontal position is increased by the
                        // method's width plus the width of the opening parenthesis
                        (0, utils_1.pipe)(utils_2.withZeroIndentation, utils_2.withZeroDotInfo, (0, utils_2.withIncreasedHorizontalPosition)(method.width + 1 + argumentGroup.map(function (_a) {
                            var width = _a.width;
                            return width;
                        }).reduce(utils_1.sum, 0) + argumentGroup.length))(config))(syntaxTree),
                    ], false);
                }, []),
            ],
            argumentsShouldStartOnNewLine: false,
            localIndentation: config.localIndentation,
            shouldStartWithDot: false,
            shouldEndWithDot: Boolean(config.shouldEndWithDot),
            width: recreatedQuery.trim().length,
        };
    }
    // shouldEndWithDot has to reside on the method object, so the end dot can be
    // placed after the method parentheses. shouldStartWithDot has to be passed on
    // further down so the start dot can be placed after the indentation.
    var argumentGroups = syntaxTree.arguments.map(function (step) { return [
        formatSyntaxTree((0, utils_1.pipe)((0, utils_2.withIncreasedIndentation)(2), utils_2.withZeroDotInfo, (0, utils_2.withHorizontalPosition)(config.localIndentation + 2))(config))(step),
    ]; });
    var lastArgumentGroup = (0, utils_1.last)(argumentGroups);
    // Add the width of the last line of parameters, the dots between them and the indentation of the parameters
    var width = lastArgumentGroup
        ? lastArgumentGroup.map(function (_a) {
            var width = _a.width;
            return width;
        }).reduce(utils_1.sum, 0) + lastArgumentGroup.length - 1
        : 0;
    return {
        type: types_1.TokenType.Method,
        method: method,
        arguments: syntaxTree.arguments,
        argumentGroups: argumentGroups,
        argumentsShouldStartOnNewLine: true,
        shouldStartWithDot: false,
        shouldEndWithDot: Boolean(config.shouldEndWithDot),
        localIndentation: 0,
        width: width,
    };
}; }; };
exports.formatMethod = formatMethod;
