// tools/github-pr-handler.ts — Handlers for create_pr_from_spec and pr_status tools.
import { createPlatformClient, getCurrentBranch, getRemoteUrl } from '../engine/github/client.js';
import { detectAuth } from '../engine/github/auth.js';
import { generatePRTitle, generatePRBody } from '../engine/github/pr-template.js';
import { findLinkedPRs } from '../engine/github/spec-linker.js';
import { validateSpecFormat } from '../core/spec-validator.js';
import { execFile as nodeExecFile } from 'node:child_process';
import { promisify } from 'node:util';
import { readFile } from 'node:fs/promises';
/* v8 ignore next 3 -- default exec, always overridden in tests */
const defaultExec = async (cmd, args) => {
    return promisify(nodeExecFile)(cmd, args, { maxBuffer: 10 * 1024 * 1024 });
};
export async function handleCreatePRFromSpec(args, exec = defaultExec) {
    const auth = await detectAuth(exec);
    if (auth.method === 'none') {
        return {
            content: [{ type: 'text', text: `GitHub auth required.\n${auth.message ?? ''}` }],
            isError: true,
        };
    }
    // Try to read spec content for PR body
    let specContent = '';
    let specPath = null;
    try {
        specPath = await findSpecPath(args.specId, exec);
        if (specPath) {
            specContent = await readFile(specPath, 'utf-8');
        }
    }
    catch {
        // Spec file not found — use minimal body
    }
    // SPEC-716: Last gate before PR creation — validate spec format.
    // Best-effort: if specPath is unknown, skip the gate rather than blocking.
    if (specPath) {
        try {
            const validationResult = await validateSpecFormat({
                id: args.specId,
                specPath,
                difficulty: 1,
                tags: [],
                dependencies: [],
                scope: 'feature',
                target: 'backend',
                type: 'feature',
                title: args.specId,
            }, { skipQuality: true });
            if (!validationResult.valid) {
                const errorList = validationResult.errors
                    .map((e) => `  - [${e.code}] ${e.message}`)
                    .join('\n');
                return {
                    content: [
                        {
                            type: 'text',
                            text: `PR creation aborted: spec format validation failed with ${String(validationResult.errors.length)} error(s):\n${errorList}\n\nFix the errors and retry.`,
                        },
                    ],
                    isError: true,
                    structuredContent: {
                        error: 'SPEC_FORMAT_INVALID',
                        code: 422,
                        context: {
                            specId: args.specId,
                            errors: validationResult.errors,
                        },
                    },
                };
            }
        }
        catch {
            // best-effort — never block PR creation due to validator errors
        }
    }
    const remoteUrl = await getRemoteUrl(exec);
    const client = createPlatformClient(remoteUrl, exec);
    const headBranch = await getCurrentBranch(exec);
    const title = generatePRTitle(args.specId, args.specId);
    const body = specContent
        ? generatePRBody(args.specId, specContent)
        : `## ${args.specId}\n\nPR created by Planu MCP Server.`;
    const result = await client.createPR({
        specId: args.specId,
        baseBranch: args.baseBranch,
        headBranch,
        title,
        body,
        draft: args.draft,
    });
    // SPEC-511: Auto-link PR to spec — fire-and-forget, never blocks response
    if (args.projectPath) {
        const projectPath = args.projectPath;
        void import('../storage/pr-store.js')
            .then(({ savePrLink }) => savePrLink(projectPath, {
            specId: args.specId,
            prUrl: result.url,
            platform: 'github',
            linkedAt: new Date().toISOString(),
            prNumber: result.number,
        }))
            .catch(() => {
            /* best-effort */
        });
    }
    return {
        content: [
            {
                type: 'text',
                text: [
                    `PR created successfully!`,
                    `  Number: #${String(result.number)}`,
                    `  Title: ${result.title}`,
                    `  State: ${result.state}`,
                    `  URL: ${result.url}`,
                ].join('\n'),
            },
        ],
    };
}
export async function handlePRStatus(args, exec = defaultExec) {
    const remoteUrl = await getRemoteUrl(exec);
    const client = createPlatformClient(remoteUrl, exec);
    if (args.specId) {
        const linked = await findLinkedPRs(client, args.specId);
        if (linked.length === 0) {
            return {
                content: [{ type: 'text', text: `No PRs found linked to ${args.specId}.` }],
            };
        }
        const text = linked.map((pr) => formatPRSummary(pr)).join('\n\n');
        return { content: [{ type: 'text', text }] };
    }
    const prs = await client.getPRStatus(args.prNumber);
    if (prs.length === 0) {
        return {
            content: [{ type: 'text', text: 'No open PRs found.' }],
        };
    }
    const text = prs.map((pr) => formatPRSummary(pr)).join('\n\n');
    return { content: [{ type: 'text', text }] };
}
function formatPRSummary(pr) {
    return [
        `#${String(pr.number)} — ${pr.title}`,
        `  Author: ${pr.author} | Branch: ${pr.branch}`,
        `  State: ${pr.state} | Review: ${pr.reviewStatus} | CI: ${pr.ciStatus}`,
        `  Changes: +${String(pr.additions)} -${String(pr.deletions)}`,
    ].join('\n');
}
async function findSpecPath(specId, exec) {
    try {
        const { stdout } = await exec('find', [
            '.',
            '-path',
            `*/SPEC-*${specId.replace('SPEC-', '')}*/spec.md`,
            '-type',
            'f',
            '-maxdepth',
            '5',
        ]);
        const first = stdout.trim().split('\n')[0];
        return first ?? null;
    }
    catch {
        return null;
    }
}
//# sourceMappingURL=github-pr-handler.js.map