"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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatClosure = void 0;
const types_1 = require("../types");
const utils_1 = require("./utils");
const layoutUtils_1 = require("../layoutUtils");
const getClosureLineOfCodeIndentation = (relativeIndentation, horizontalPosition, methodWidth, lineNumber, shouldStartWithDot) => {
    if (lineNumber === 0)
        return Math.max(relativeIndentation, 0);
    return Math.max(relativeIndentation + horizontalPosition + methodWidth + (shouldStartWithDot ? 1 : 0) + 1, 0);
};
const getFormattedClosureLineOfCode = (horizontalPosition, methodWidth, shouldStartWithDot) => ({ lineOfCode, relativeIndentation }, lineNumber) => ({
    lineOfCode,
    relativeIndentation,
    localIndentation: getClosureLineOfCodeIndentation(relativeIndentation, horizontalPosition, methodWidth, lineNumber, shouldStartWithDot),
});
const getFormattedClosureCodeBlock = (unformattedClosureCodeBlock, horizontalPosition, methodWidth, shouldStartWithDot) => {
    return unformattedClosureCodeBlock.map(getFormattedClosureLineOfCode(horizontalPosition, methodWidth, shouldStartWithDot));
};
const formatClosure = (formatSyntaxTree) => (config) => (syntaxTree) => {
    const { closureCodeBlock: unformattedClosureCodeBlock, method: unformattedMethod } = syntaxTree;
    const { localIndentation, horizontalPosition, maxLineLength, shouldEndWithDot, shouldStartWithDot, } = config;
    const formattedMethod = formatSyntaxTree((0, utils_1.withNoEndDotInfo)(config))(unformattedMethod);
    const methodWidth = formattedMethod.width;
    if ((0, layoutUtils_1.willFitOnLine)(syntaxTree, config, horizontalPosition)) {
        return {
            type: types_1.TokenType.Closure,
            method: formattedMethod,
            closureCodeBlock: getFormattedClosureCodeBlock(unformattedClosureCodeBlock, horizontalPosition, methodWidth, shouldStartWithDot),
            localIndentation,
            width: (0, layoutUtils_1.getOneLinerWidth)(syntaxTree, horizontalPosition),
            shouldStartWithDot: false,
            shouldEndWithDot: Boolean(shouldEndWithDot),
        };
    }
    return {
        type: types_1.TokenType.Closure,
        method: formattedMethod,
        closureCodeBlock: getFormattedClosureCodeBlock(unformattedClosureCodeBlock, horizontalPosition, methodWidth, shouldStartWithDot),
        localIndentation: 0,
        width: 0,
        shouldStartWithDot: false,
        shouldEndWithDot: Boolean(shouldEndWithDot),
    };
};
exports.formatClosure = formatClosure;
