import { execSync } from 'node:child_process';
import { obterConfigInstalacao } from '../app/installation-store.js';
import { cloneRepo, escreverAskpassScript, getInstallationToken, limparAskpassScript } from '../app/repo-downloader.js';
import { statsStore } from '../dashboard/stats-store.js';
import { rodarAnaliseCodigo } from './analysis-core.js';
import { gerarComentarioAtualizacaoRelatorio, gerarCorpoPrRelatorio, gerarResumoReviewPr, gerarTituloPrRelatorio } from './push-report.js';
const MAX_REVIEW_COMMENTS = 40;
const PREFIXOS_BRANCH_REJEITADOS = ['tutanus/analise-', 'tutanus-fix-', 'tutanus/diagnostico-'];
async function obterPrAberto(octokit, owner, repo, headBranch, baseBranch) {
    const { data } = await octokit.request('GET /repos/{owner}/{repo}/pulls', {
        owner,
        repo,
        head: `${owner}:${headBranch}`,
        base: baseBranch,
        state: 'open'
    }).catch(() => ({ data: [] }));
    const pr = data[0];
    if (!pr)
        return null;
    return { number: pr.number, headSha: pr.head.sha };
}
async function criarOuAtualizarPr(octokit, owner, repo, baseBranch, branchReport, body, titulo) {
    const existente = await obterPrAberto(octokit, owner, repo, branchReport, baseBranch);
    if (existente) {
        return { ...existente, created: false };
    }
    const { data: pr } = await octokit.request('POST /repos/{owner}/{repo}/pulls', {
        owner,
        repo,
        title: titulo,
        head: branchReport,
        base: baseBranch,
        body,
        maintainer_can_modify: true
    });
    return { number: pr.number, headSha: pr.head.sha, created: true };
}
async function comentarNoPr(octokit, owner, repo, prNumber, body) {
    await octokit.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
        owner,
        repo,
        issue_number: prNumber,
        body
    });
}
async function publicarReviewComentarios(octokit, owner, repo, prNumber, commitId, ocorrencias) {
    const comentarios = ocorrencias
        .filter(o => o.relPath && o.linha && o.linha > 0)
        .slice(0, MAX_REVIEW_COMMENTS)
        .map(o => ({
        path: o.relPath,
        line: o.linha,
        body: `**${(o.nivel || 'info').toUpperCase()}** · ${o.tipo || 'geral'}\n\n${o.mensagem}${o.sugestao ? `\n\n**Sugestão:** ${o.sugestao}` : ''}`
    }));
    if (comentarios.length === 0)
        return;
    try {
        await octokit.request('POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews', {
            owner,
            repo,
            pull_number: prNumber,
            commit_id: commitId,
            event: 'COMMENT',
            body: gerarResumoReviewPr(ocorrencias.length, comentarios.length),
            comments: comentarios
        });
    }
    catch (err) {
        const { GithubWebhookMensagens } = await import('../../../core/messages/index.js');
        const { messages: msgs } = await import('../../../core/messages/index.js');
        msgs.log.aviso(GithubWebhookMensagens.naoFoiPossivelPublicarReview(err instanceof Error ? err.message : String(err)));
    }
}
export async function executarAnalisePush(app, params) {
    const { installationId, owner, repo, branch, commitMessage } = params;
    let headSha = params.headSha;
    const config = obterConfigInstalacao(installationId);
    if (!config.pushAnalysisEnabled)
        return;
    if (PREFIXOS_BRANCH_REJEITADOS.some(p => branch.startsWith(p))) {
        return;
    }
    const octokit = await app.getInstallationOctokit(installationId);
    if (!headSha) {
        const refData = await octokit.request('GET /repos/{owner}/{repo}/git/ref/heads/{branch}', {
            owner,
            repo,
            branch
        }).catch(() => null);
        if (!refData)
            return;
        headSha = refData.data.object.sha;
    }
    const repoResp = await octokit.request('GET /repos/{owner}/{repo}', {
        owner,
        repo
    }).catch(() => null);
    const defaultBranch = repoResp?.data?.default_branch ?? 'main';
    const { resultado, ctx, cleanup } = await rodarAnaliseCodigo(app, {
        installationId,
        owner,
        repo,
        headSha,
        branch,
        commitMessage,
        baseSha: params.beforeSha,
        incremental: config.incrementalOnPush
    });
    try {
        ctx.baseRef = defaultBranch;
        const tituloPr = gerarTituloPrRelatorio(branch, resultado.scoreGeral, defaultBranch);
        const corpoPr = gerarCorpoPrRelatorio(resultado, ctx);
        let headBranch = branch;
        if (branch === defaultBranch) {
            headBranch = `tutanus/diagnostico-${branch}-${Date.now()}`;
            const { repoDir, cleanup: cloneCleanup } = await cloneRepo(app, installationId, owner, repo, branch);
            try {
                execSync(`git checkout -b "${headBranch}"`, { cwd: repoDir, stdio: 'pipe' });
                const token = await getInstallationToken(app, installationId);
                const askpassScript = escreverAskpassScript();
                const repoUrl = `https://github.com/${owner}/${repo}.git`;
                try {
                    execSync(`git push "${repoUrl}" HEAD:${headBranch}`, {
                        cwd: repoDir,
                        stdio: 'pipe',
                        timeout: 60000,
                        env: {
                            ...process.env,
                            TUTANUS_GIT_TOKEN: token,
                            GIT_ASKPASS: askpassScript,
                            GIT_TERMINAL_PROMPT: '0'
                        }
                    });
                }
                finally {
                    limparAskpassScript(askpassScript);
                }
            }
            finally {
                cloneCleanup();
            }
        }
        const prInfo = await criarOuAtualizarPr(octokit, owner, repo, defaultBranch, headBranch, corpoPr, tituloPr);
        if (!prInfo.created) {
            await comentarNoPr(octokit, owner, repo, prInfo.number, gerarComentarioAtualizacaoRelatorio(resultado, ctx));
        }
        const { data: prHead } = await octokit.request('GET /repos/{owner}/{repo}/pulls/{pull_number}', {
            owner,
            repo,
            pull_number: prInfo.number
        });
        await publicarReviewComentarios(octokit, owner, repo, prInfo.number, prHead.head.sha, resultado.ocorrencias);
        statsStore.recordAnalysis({
            repository: `${owner}/${repo}`,
            event: 'push',
            score: resultado.scoreGeral,
            workflowsCount: 0,
            occurrencesCount: resultado.totalOcorrencias
        });
    }
    finally {
        cleanup();
    }
}
//# sourceMappingURL=push-analysis-service.js.map