"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSelectionRanges = void 0;
const vscode_languageserver_types_1 = require("vscode-languageserver-types");
const yaml_documents_1 = require("../parser/yaml-documents");
function getSelectionRanges(document, positions) {
    if (!document) {
        return;
    }
    const doc = yaml_documents_1.yamlDocumentsCache.getYamlDocument(document);
    return positions.map((position) => {
        const ranges = getRanges(position);
        let current;
        for (const range of ranges) {
            current = vscode_languageserver_types_1.SelectionRange.create(range, current);
        }
        if (!current) {
            current = vscode_languageserver_types_1.SelectionRange.create({
                start: position,
                end: position,
            });
        }
        return current;
    });
    function getRanges(position) {
        const offset = document.offsetAt(position);
        const result = [];
        for (const ymlDoc of doc.documents) {
            let currentNode;
            let firstNodeOffset;
            let isFirstNode = true;
            ymlDoc.visit((node) => {
                const endOffset = node.offset + node.length;
                // Skip if end offset doesn't even reach cursor position
                if (endOffset < offset) {
                    return true;
                }
                let startOffset = node.offset;
                // Recheck start offset with the trimmed one in case of this
                // key:
                //   - value
                // ↑
                if (startOffset > offset) {
                    const nodePosition = document.positionAt(startOffset);
                    if (nodePosition.line !== position.line) {
                        return true;
                    }
                    const lineBeginning = { line: nodePosition.line, character: 0 };
                    const text = document.getText({
                        start: lineBeginning,
                        end: nodePosition,
                    });
                    if (text.trim().length !== 0) {
                        return true;
                    }
                    startOffset = document.offsetAt(lineBeginning);
                    if (startOffset > offset) {
                        return true;
                    }
                }
                // Allow equal for children to override
                if (!currentNode || startOffset >= currentNode.offset) {
                    currentNode = node;
                    firstNodeOffset = startOffset;
                }
                return true;
            });
            while (currentNode) {
                const startOffset = isFirstNode ? firstNodeOffset : currentNode.offset;
                const endOffset = currentNode.offset + currentNode.length;
                const range = {
                    start: document.positionAt(startOffset),
                    end: document.positionAt(endOffset),
                };
                const text = document.getText(range);
                const trimmedText = text.trimEnd();
                const trimmedLength = text.length - trimmedText.length;
                if (trimmedLength > 0) {
                    range.end = document.positionAt(endOffset - trimmedLength);
                }
                // Add a jump between '' "" {} []
                const isSurroundedBy = (startCharacter, endCharacter) => {
                    return trimmedText.startsWith(startCharacter) && trimmedText.endsWith(endCharacter || startCharacter);
                };
                if ((currentNode.type === 'string' && (isSurroundedBy("'") || isSurroundedBy('"'))) ||
                    (currentNode.type === 'object' && isSurroundedBy('{', '}')) ||
                    (currentNode.type === 'array' && isSurroundedBy('[', ']'))) {
                    result.push({
                        start: document.positionAt(startOffset + 1),
                        end: document.positionAt(endOffset - 1),
                    });
                }
                result.push(range);
                currentNode = currentNode.parent;
                isFirstNode = false;
            }
            // A position can't be in multiple documents
            if (result.length > 0) {
                break;
            }
        }
        return result.reverse();
    }
}
exports.getSelectionRanges = getSelectionRanges;
//# sourceMappingURL=yamlSelectionRanges.js.map