// engine/github/adapters/github-adapter.ts — Full GitHub implementation via gh CLI.
import { ghJson, ghRaw } from '../gh-cli.js';
export class GitHubAdapter {
    exec;
    constructor(exec) {
        this.exec = exec;
    }
    async createPR(input) {
        const args = [
            'pr',
            'create',
            '--base',
            input.baseBranch,
            '--head',
            input.headBranch,
            '--title',
            input.title,
            '--body',
            input.body,
            '--json',
            'url,number,title,isDraft',
        ];
        if (input.draft) {
            args.push('--draft');
        }
        const result = await ghJson(args, this.exec);
        return {
            url: result.url,
            number: result.number,
            title: result.title,
            state: result.isDraft ? 'draft' : 'open',
        };
    }
    async createIssue(input) {
        const args = [
            'issue',
            'create',
            '--title',
            input.title,
            '--body',
            input.body,
            '--json',
            'url,number,title,labels',
        ];
        if (input.labels && input.labels.length > 0) {
            args.push('--label', input.labels.join(','));
        }
        const result = await ghJson(args, this.exec);
        return {
            url: result.url,
            number: result.number,
            title: result.title,
            labels: result.labels.map((l) => l.name),
        };
    }
    async getPRStatus(prNumber) {
        const fields = 'number,title,author,headRefName,baseRefName,state,isDraft,' +
            'reviewDecision,statusCheckRollup,additions,deletions,changedFiles';
        const args = prNumber
            ? ['pr', 'view', String(prNumber), '--json', fields]
            : ['pr', 'list', '--json', fields, '--limit', '30'];
        const raw = prNumber
            ? [await ghJson(args, this.exec)]
            : await ghJson(args, this.exec);
        return raw.map((pr) => this.mapPRStatus(pr));
    }
    async getPRDiff(prNumber) {
        return ghRaw(['pr', 'diff', String(prNumber)], this.exec);
    }
    async listIssues(state = 'open') {
        const args = [
            'issue',
            'list',
            '--state',
            state,
            '--json',
            'url,number,title,labels',
            '--limit',
            '50',
        ];
        const raw = await ghJson(args, this.exec);
        return raw.map((issue) => ({
            url: issue.url,
            number: issue.number,
            title: issue.title,
            labels: issue.labels.map((l) => l.name),
        }));
    }
    async createRelease(input) {
        const args = [
            'release',
            'create',
            `v${input.version}`,
            '--title',
            `v${input.version}`,
            '--json',
            'url,tagName',
        ];
        if (input.draft) {
            args.push('--draft');
        }
        if (input.prerelease) {
            args.push('--prerelease');
        }
        if (input.generateNotes) {
            args.push('--generate-notes');
        }
        return ghJson(args, this.exec);
    }
    async addLabels(issueNumber, labels) {
        const args = ['issue', 'edit', String(issueNumber), '--add-label', labels.join(',')];
        await ghRaw(args, this.exec);
    }
    async getCIStatus(ref) {
        try {
            const raw = await ghJson(['pr', 'checks', ref, '--json', 'name,state,conclusion,detailsUrl'], this.exec);
            return raw.map((check) => ({
                name: check.name,
                status: this.mapCheckStatus(check.state),
                conclusion: this.mapConclusion(check.conclusion),
                url: check.detailsUrl,
            }));
        }
        catch {
            return [];
        }
    }
    mapPRStatus(pr) {
        const checks = (pr.statusCheckRollup ?? []).map((c) => ({
            name: c.name,
            status: this.mapCheckStatus(c.status),
            conclusion: this.mapConclusion(c.conclusion),
            url: c.detailsUrl,
        }));
        return {
            number: pr.number,
            title: pr.title,
            author: pr.author.login,
            branch: pr.headRefName,
            baseBranch: pr.baseRefName,
            state: this.mapPRState(pr.state, pr.isDraft),
            reviewStatus: this.mapReviewDecision(pr.reviewDecision),
            ciStatus: this.deriveCIStatus(checks),
            checks,
            additions: pr.additions,
            deletions: pr.deletions,
            changedFiles: pr.changedFiles,
        };
    }
    mapPRState(state, isDraft) {
        if (isDraft) {
            return 'draft';
        }
        const lower = state.toLowerCase();
        if (lower === 'merged') {
            return 'merged';
        }
        if (lower === 'closed') {
            return 'closed';
        }
        return 'open';
    }
    mapReviewDecision(decision) {
        const d = decision.toUpperCase();
        if (d === 'APPROVED') {
            return 'approved';
        }
        if (d === 'CHANGES_REQUESTED') {
            return 'changes_requested';
        }
        if (d === 'REVIEW_REQUIRED') {
            return 'pending';
        }
        return 'none';
    }
    mapCheckStatus(status) {
        const s = status.toLowerCase();
        if (s === 'completed' || s === 'success' || s === 'failure') {
            return 'completed';
        }
        if (s === 'in_progress' || s === 'pending') {
            return 'in_progress';
        }
        return 'queued';
    }
    mapConclusion(conclusion) {
        if (!conclusion) {
            return null;
        }
        const c = conclusion.toLowerCase();
        if (c === 'success') {
            return 'success';
        }
        if (c === 'failure') {
            return 'failure';
        }
        if (c === 'neutral') {
            return 'neutral';
        }
        if (c === 'skipped') {
            return 'skipped';
        }
        if (c === 'cancelled') {
            return 'cancelled';
        }
        return null;
    }
    deriveCIStatus(checks) {
        if (checks.length === 0) {
            return 'none';
        }
        if (checks.some((c) => c.conclusion === 'failure')) {
            return 'failure';
        }
        if (checks.every((c) => c.conclusion === 'success')) {
            return 'success';
        }
        return 'pending';
    }
}
//# sourceMappingURL=github-adapter.js.map