import { limitarLinhasEmBranco, normalizarFimDeLinha, normalizarNewlinesFinais, removerEspacosFinaisPorLinha } from './commons.js';
function parseYamlLines(code) {
    const lines = normalizarFimDeLinha(code).split('\n');
    const result = [];
    let inMultiline = false;
    let multilineBlock = null;
    let multilineIndent = 0;
    for (const raw of lines) {
        const trimmed = raw.trimStart();
        const indent = raw.length - trimmed.length;
        if (inMultiline) {
            if (trimmed === '' || indent >= multilineIndent) {
                result.push({
                    raw,
                    indent,
                    content: trimmed,
                    kind: 'multiline-content',
                    inMultiline: true,
                    multilineBlock
                });
                continue;
            }
            else {
                inMultiline = false;
                multilineBlock = null;
            }
        }
        if (!trimmed) {
            result.push({
                raw,
                indent,
                content: '',
                kind: 'empty',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (trimmed.startsWith('#')) {
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'comment',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (trimmed.startsWith('%')) {
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'directive',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (trimmed.startsWith('---') || trimmed.startsWith('...')) {
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'directive',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (/^-\s/.test(trimmed)) {
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'sequence',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (/^[^\n:]+:\s/.test(trimmed) || /^[^\n:]+:$/.test(trimmed)) {
            const multilineMatch = trimmed.match(/:\s*\|[\+\-]?\s*$/);
            const multilineFolded = trimmed.match(/:\s*>[\+\-]?\s*$/);
            if (multilineMatch || multilineFolded) {
                inMultiline = true;
                multilineBlock = multilineMatch ? 'literal' : 'folded';
                multilineIndent = indent + 2;
                result.push({
                    raw,
                    indent,
                    content: trimmed,
                    kind: 'multiline-start',
                    inMultiline: false,
                    multilineBlock: null
                });
                continue;
            }
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'mapping',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        if (trimmed.startsWith('&') || trimmed.startsWith('*')) {
            result.push({
                raw,
                indent,
                content: trimmed,
                kind: 'anchor',
                inMultiline: false,
                multilineBlock: null
            });
            continue;
        }
        result.push({
            raw,
            indent,
            content: trimmed,
            kind: 'scalar',
            inMultiline: false,
            multilineBlock: null
        });
    }
    return result;
}
function corrigirIndentacaoYaml(lines) {
    const indentSize = 2;
    const out = [];
    let changed = false;
    for (const line of lines) {
        if (line.kind === 'empty' || line.kind === 'comment') {
            out.push(line);
            continue;
        }
        if (line.inMultiline || line.kind === 'multiline-content') {
            out.push(line);
            continue;
        }
        if (line.raw.includes('\t')) {
            const tabCount = (line.raw.match(/\t/g) ?? []).length;
            const spaces = ' '.repeat(tabCount * indentSize);
            const fixed = line.raw.replace(/\t/g, spaces);
            const newIndent = fixed.length - fixed.trimStart().length;
            out.push({
                ...line,
                raw: fixed,
                indent: newIndent
            });
            changed = true;
            continue;
        }
        if (line.indent > 0 && line.indent % indentSize !== 0) {
            const correctIndent = Math.round(line.indent / indentSize) * indentSize;
            const fixed = ' '.repeat(correctIndent) + line.content;
            out.push({
                ...line,
                raw: fixed,
                indent: correctIndent
            });
            changed = true;
            continue;
        }
        out.push(line);
    }
    return changed ? out : lines;
}
function corrigirEspacamentoYaml(lines) {
    const out = [];
    let changed = false;
    for (const line of lines) {
        if (line.kind === 'empty' || line.kind === 'comment' || line.kind === 'directive' || line.kind === 'multiline-content') {
            out.push(line);
            continue;
        }
        let fixed = line.raw;
        if (/^(\s*)-\S/.test(fixed)) {
            fixed = fixed.replace(/^(\s*)-(\S)/, '$1- $2');
            changed = true;
        }
        if (!fixed.includes('"') && !fixed.includes("'")) {
            if (/^(\s*[^\n:]+):(\S)/.test(fixed)) {
                fixed = fixed.replace(/^(\s*[^\n:]+):(\S)/, '$1: $2');
                changed = true;
            }
        }
        if (/\S#\s/.test(fixed) && !fixed.includes('"#') && !fixed.includes("'#")) {
            fixed = fixed.replace(/(\S)#/, '$1 #');
            changed = true;
        }
        if (fixed !== line.raw) {
            const newIndent = fixed.length - fixed.trimStart().length;
            out.push({
                ...line,
                raw: fixed,
                indent: newIndent,
                content: fixed.trimStart()
            });
        }
        else {
            out.push(line);
        }
    }
    return changed ? out : lines;
}
function corrigirChavesDuplicadas(lines) {
    const warnings = [];
    const seenKeys = new Map();
    const out = [];
    for (const line of lines) {
        if (line.kind === 'mapping') {
            const keyMatch = line.content.match(/^([^:]+):/);
            if (keyMatch) {
                const key = (keyMatch[1] ?? '').trim();
                if (seenKeys.has(key)) {
                    const count = (seenKeys.get(key) ?? 0) + 1;
                    warnings.push(`Chave duplicada "${key}" na linha ${(seenKeys.get(key) ?? 0) + 1} e ${out.length + 1}`);
                    seenKeys.set(key, count);
                }
                else {
                    seenKeys.set(key, out.length);
                }
            }
        }
        out.push(line);
    }
    return {
        lines: out,
        warnings
    };
}
function corrigirStringsMultilineYaml(lines) {
    const out = [];
    let indice = 0;
    while (indice < lines.length) {
        const line = lines[indice];
        if (line === undefined)
            break;
        if (line.kind === 'multiline-start') {
            out.push(line);
            indice++;
            const contentLines = [];
            while (indice < lines.length && (lines[indice]?.kind === 'multiline-content' || lines[indice]?.kind === 'empty')) {
                const cl = lines[indice];
                if (cl)
                    contentLines.push(cl);
                indice++;
            }
            if (contentLines.length > 0) {
                const firstContent = contentLines.find(linha => linha.kind === 'multiline-content');
                if (firstContent) {
                    out.push(...contentLines);
                }
            }
            continue;
        }
        out.push(line);
        indice++;
    }
    return out;
}
export function formatarYamlMinimo(code) {
    const normalized = normalizarFimDeLinha(code);
    const trimmed = removerEspacosFinaisPorLinha(normalized);
    const parsedLines = parseYamlLines(trimmed);
    let lines = corrigirIndentacaoYaml(parsedLines);
    lines = corrigirEspacamentoYaml(lines);
    lines = corrigirStringsMultilineYaml(lines);
    const { lines: finalLines, warnings } = corrigirChavesDuplicadas(lines);
    const rebuilt = finalLines.map(linha => linha.raw).join('\n');
    const { code: semBlanks } = limitarLinhasEmBranco(rebuilt, 2);
    const formatted = normalizarNewlinesFinais(semBlanks);
    const baseline = normalizarNewlinesFinais(normalized);
    const anyChanged = formatted !== baseline;
    return {
        ok: true,
        parser: 'yaml',
        formatted,
        changed: anyChanged,
        reason: anyChanged ? `estilo-tutanus-yaml(indent:${parsedLines.some(linha => linha.raw.includes('\t')) ? 'fixed' : 'ok'},dupKeys:${warnings.length > 0 ? 'detected' : 'none'})` : 'normalizacao-basica'
    };
}
//# sourceMappingURL=yaml.js.map