"use strict";
/**
 * Shared helpers for the `setup-branch-protection` and `setup-prebuild`
 * CLI subcommands. Both wrap GitHub API calls behind `gh api` for the
 * common path, with consistent detection / error messaging / repo
 * resolution. Co-locating the shared surface keeps the two subcommand
 * modules focused on payload construction.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GhError = void 0;
exports.ghCliAvailable = ghCliAvailable;
exports.resolveOwnerRepo = resolveOwnerRepo;
exports.resolveDefaultBranch = resolveDefaultBranch;
exports.ghApi = ghApi;
exports.renderGhError = renderGhError;
exports.preflightGhCli = preflightGhCli;
const child_process_1 = require("child_process");
const logger = __importStar(require("./logger"));
class GhError extends Error {
    httpStatus;
    suggestion;
    constructor(message, opts) {
        super(message);
        this.name = 'GhError';
        this.httpStatus = opts?.httpStatus;
        this.suggestion = opts?.suggestion;
    }
}
exports.GhError = GhError;
/**
 * Returns true if `gh` is on PATH and authenticated.
 *
 * Both setup-branch-protection and setup-prebuild require the gh CLI
 * (we don't ship an octokit-based fallback in 2.5.2 — keeps the
 * dependency surface narrow). Future octokit fallback would slot in
 * here without changing callers.
 */
function ghCliAvailable() {
    try {
        (0, child_process_1.execSync)('gh --version', { stdio: 'pipe' });
        (0, child_process_1.execSync)('gh auth status', { stdio: 'pipe' });
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Resolve the owner+repo of the current git working tree using
 * `gh repo view --json owner,name`. Requires gh to be authenticated
 * AND the repo to have a github.com remote configured (gh respects
 * the same git-remote conventions).
 *
 * Throws GhError with actionable suggestion on every failure path so
 * the callers can render a clean error to the customer.
 */
function resolveOwnerRepo(cwd) {
    try {
        const out = (0, child_process_1.execSync)('gh repo view --json owner,name', {
            cwd,
            stdio: ['ignore', 'pipe', 'pipe'],
            encoding: 'utf-8',
        });
        const parsed = JSON.parse(out);
        if (!parsed.owner?.login || !parsed.name) {
            throw new GhError('gh repo view returned an unexpected payload — re-run `gh auth login`.');
        }
        return { owner: parsed.owner.login, repo: parsed.name };
    }
    catch (e) {
        if (e instanceof GhError)
            throw e;
        const msg = e.stderr?.toString() ?? e.message;
        if (msg.includes('not a git repository') || msg.includes('no remote')) {
            throw new GhError('Repo has no github.com remote configured. Add the remote and push first.', {
                suggestion: 'git remote add origin git@github.com:OWNER/REPO.git && git push -u origin main',
            });
        }
        throw new GhError(`Could not resolve repo via gh: ${msg.trim().split('\n')[0]}`, {
            suggestion: 'Run `gh auth login` and confirm `gh repo view` works.',
        });
    }
}
/**
 * Resolve the repo's default branch via `gh repo view --json
 * defaultBranchRef`. Used as the default `--branch` when the customer
 * doesn't pass one explicitly — most repos use `main` but legacy
 * repos may still default to `master` etc.
 */
function resolveDefaultBranch(cwd) {
    try {
        const out = (0, child_process_1.execSync)('gh repo view --json defaultBranchRef', {
            cwd,
            stdio: ['ignore', 'pipe', 'pipe'],
            encoding: 'utf-8',
        });
        const parsed = JSON.parse(out);
        if (parsed.defaultBranchRef?.name)
            return parsed.defaultBranchRef.name;
    }
    catch {
        /* fall through to fallback */
    }
    return 'main';
}
/**
 * Call `gh api` with the given args and return the parsed JSON body.
 * Throws GhError with the parsed HTTP status when the call fails so
 * callers can branch on 403 / 404 / 422 specifically.
 *
 * `args` should NOT include the `-X METHOD` flag — pass it via
 * `opts.method`. The endpoint is added at the end.
 */
function ghApi(endpoint, opts) {
    const args = ['api'];
    if (opts.method && opts.method !== 'GET')
        args.push('-X', opts.method);
    if (opts.inputJson)
        args.push('--input', '-');
    if (opts.extraArgs)
        args.push(...opts.extraArgs);
    args.push(endpoint);
    try {
        const out = (0, child_process_1.execSync)(`gh ${args.map((a) => JSON.stringify(a)).join(' ')}`, {
            cwd: opts.cwd,
            stdio: opts.inputJson ? ['pipe', 'pipe', 'pipe'] : ['ignore', 'pipe', 'pipe'],
            encoding: 'utf-8',
            input: opts.inputJson,
        });
        return out.trim() ? JSON.parse(out) : null;
    }
    catch (e) {
        const stderr = (e.stderr?.toString() ?? '').trim();
        const statusMatch = stderr.match(/HTTP (\d+):/);
        const httpStatus = statusMatch ? parseInt(statusMatch[1], 10) : undefined;
        if (httpStatus === 403) {
            throw new GhError('Permission denied — you need admin rights on the repo.', {
                httpStatus,
                suggestion: 'Ask a repo admin to run this command, or configure manually in repo Settings.',
            });
        }
        if (httpStatus === 404) {
            throw new GhError('Endpoint not found — repo may not exist or you may lack access.', {
                httpStatus,
                suggestion: 'Verify the repo via `gh repo view`.',
            });
        }
        throw new GhError(`gh api failed (HTTP ${httpStatus ?? '?'}): ${stderr.split('\n')[0]}`, {
            httpStatus,
        });
    }
}
/**
 * Render a GhError to the customer. Returns the exit code the CLI
 * should use (always 1 for now, but kept as a separate return for
 * future "warn but don't fail" cases).
 */
function renderGhError(err, context) {
    logger.fail(`${context}: ${err.message}`);
    if (err.suggestion)
        logger.dim(`  → ${err.suggestion}`);
    return 1;
}
/**
 * Pre-flight check shared by both setup commands. Verifies gh CLI is
 * available + authenticated. Renders the manual-fallback instructions
 * if gh is missing rather than throwing — keeps the customer's
 * troubleshooting path consistent.
 *
 * Returns true if pre-flight passes; false (with rendered error) if not.
 */
function preflightGhCli(commandName) {
    if (ghCliAvailable())
        return true;
    logger.fail(`${commandName}: gh CLI not available or not authenticated.`);
    logger.dim('  → Install gh: https://cli.github.com');
    logger.dim('  → Authenticate: `gh auth login`');
    return false;
}
//# sourceMappingURL=setup-gh.js.map