import { corrigirPontuacaoECodigo, limitarLinhasEmBranco, normalizarFimDeLinha, normalizarNewlinesFinais, removerBom } from './commons.js';
function parseShellLine(raw, ctx) {
    const trimmed = raw.trimEnd();
    if (ctx.inHereDoc) {
        const isEnd = ctx.hereDocStripTabs ? trimmed.trim() === ctx.hereDocDelimiter : trimmed === ctx.hereDocDelimiter;
        if (isEnd) {
            return {
                output: trimmed,
                ctx: {
                    ...ctx,
                    inHereDoc: false,
                    hereDocDelimiter: '',
                    hereDocStripTabs: false
                }
            };
        }
        return {
            output: trimmed,
            ctx
        };
    }
    if (!trimmed.trim()) {
        return {
            output: trimmed,
            ctx
        };
    }
    if (/^\s*#/.test(trimmed)) {
        return {
            output: trimmed,
            ctx
        };
    }
    let inSingleQuote = ctx.inSingleQuote;
    let inDoubleQuote = ctx.inDoubleQuote;
    let escaped = false;
    let indice = 0;
    while (indice < trimmed.length) {
        const ch = trimmed[indice];
        if (ch === undefined)
            break;
        if (escaped) {
            escaped = false;
            indice++;
            continue;
        }
        if (ch === '\\') {
            if (indice === trimmed.length - 1 && !inSingleQuote) {
                return {
                    output: trimmed,
                    ctx: {
                        ...ctx,
                        continuation: true
                    }
                };
            }
            escaped = true;
            indice++;
            continue;
        }
        if (inSingleQuote) {
            if (ch === "'") {
                inSingleQuote = false;
            }
            indice++;
            continue;
        }
        if (inDoubleQuote) {
            if (ch === '"') {
                inDoubleQuote = false;
            }
            indice++;
            continue;
        }
        if (ch === "'") {
            inSingleQuote = true;
            indice++;
            continue;
        }
        if (ch === '"') {
            inDoubleQuote = true;
            indice++;
            continue;
        }
        if (ch === '<') {
            const rest = trimmed.slice(indice);
            const hereDocMatch = rest.match(/<<-?\s*['"]?(\w+)['"]?/);
            if (hereDocMatch) {
                const delimiter = hereDocMatch[1] ?? '';
                const stripTabs = rest.includes('<<-');
                return {
                    output: trimmed,
                    ctx: {
                        ...ctx,
                        inHereDoc: true,
                        hereDocDelimiter: delimiter,
                        hereDocStripTabs: stripTabs,
                        continuation: false
                    }
                };
            }
        }
        indice++;
    }
    const endsWithBackslash = trimmed.endsWith('\\') && !escaped;
    if (endsWithBackslash && !inSingleQuote && !inDoubleQuote) {
        return {
            output: trimmed,
            ctx: {
                ...ctx,
                continuation: true
            }
        };
    }
    return {
        output: trimmed,
        ctx: {
            ...ctx,
            inSingleQuote,
            inDoubleQuote,
            continuation: false
        }
    };
}
function corrigirEspacamentoShell(lines) {
    const out = [];
    let ctx = {
        inHereDoc: false,
        hereDocDelimiter: '',
        hereDocStripTabs: false,
        inSingleQuote: false,
        inDoubleQuote: false,
        continuation: false,
        caseBlock: false,
        functionBlock: false
    };
    for (const raw of lines) {
        const { output, ctx: newCtx } = parseShellLine(raw, ctx);
        ctx = newCtx;
        if (ctx.inHereDoc) {
            out.push(output);
            continue;
        }
        if (!output.trim()) {
            out.push(output);
            continue;
        }
        if (/^\s*#\S/.test(output)) {
            out.push(output.replace(/^(\s*)#(\S)/, '$1# $2'));
            continue;
        }
        if (/^\s*[a-zA-Z_][\w]*\s+=\s/.test(output) && !output.includes('[')) {
            out.push(output.replace(/^(\s*[a-zA-Z_][\w]*)\s+=\s/, '$1='));
            continue;
        }
        if (/\S\|\S/.test(output)) {
            out.push(output.replace(/(\S)\|(\S)/g, '$1 | $2'));
            continue;
        }
        if (/\S[><]\S/.test(output)) {
            out.push(output.replace(/(\S)([><])(\S)/g, '$1 $2 $3'));
            continue;
        }
        out.push(output);
    }
    return out;
}
export function formatarShellMinimo(code) {
    const normalized = normalizarFimDeLinha(removerBom(code));
    const lines = normalized.split('\n');
    const comEspacamento = corrigirEspacamentoShell(lines);
    const { code: limitedBlanks } = limitarLinhasEmBranco(comEspacamento.join('\n'), 2);
    const { text: comPontuacao, stats } = corrigirPontuacaoECodigo(limitedBlanks);
    const formatted = normalizarNewlinesFinais(comPontuacao);
    const baseline = normalizarNewlinesFinais(normalized);
    const anyChanged = formatted !== baseline;
    return {
        ok: true,
        parser: 'shell',
        formatted,
        changed: anyChanged,
        reason: anyChanged ? `estilo-tutanus-shell(punct:${stats.pontuacaoRepetida},space:${stats.espacamentoIncorreto},ops:${stats.operadoresRelacionais})` : 'normalizacao-basica'
    };
}
//# sourceMappingURL=shell.js.map