"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRepoGitUrl = exports.getInvalidReviewers = exports.isInvalidReviewersResponse = exports.accumulateValues = exports.prInfo = exports.BITBUCKET_INVALID_REVIEWERS_EXCEPTION = void 0;
const tslib_1 = require("tslib");
// SEE for the reference https://github.com/renovatebot/renovate/blob/c3e9e572b225085448d94aa121c7ec81c14d3955/lib/platform/bitbucket/utils.js
const url_1 = tslib_1.__importDefault(require("url"));
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const error_messages_1 = require("../../../constants/error-messages");
const logger_1 = require("../../../logger");
const git = tslib_1.__importStar(require("../../../util/git"));
const bitbucket_server_1 = require("../../../util/http/bitbucket-server");
const url_2 = require("../../../util/url");
const pr_body_1 = require("../pr-body");
exports.BITBUCKET_INVALID_REVIEWERS_EXCEPTION = 'com.atlassian.bitbucket.pull.InvalidPullRequestReviewersException';
const bitbucketServerHttp = new bitbucket_server_1.BitbucketServerHttp();
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp250
const prStateMapping = {
    MERGED: 'merged',
    DECLINED: 'closed',
    OPEN: 'open',
};
function prInfo(pr) {
    return {
        version: pr.version,
        number: pr.id,
        bodyStruct: (0, pr_body_1.getPrBodyStruct)(pr.description),
        sourceBranch: pr.fromRef.displayId,
        targetBranch: pr.toRef.displayId,
        title: pr.title,
        state: prStateMapping[pr.state],
        createdAt: pr.createdDate,
    };
}
exports.prInfo = prInfo;
const addMaxLength = (inputUrl, limit = 100) => {
    const { search, ...parsedUrl } = url_1.default.parse(inputUrl, true);
    const maxedUrl = url_1.default.format({
        ...parsedUrl,
        query: { ...parsedUrl.query, limit },
    });
    return maxedUrl;
};
function callApi(apiUrl, method, options) {
    /* istanbul ignore next */
    switch (method.toLowerCase()) {
        case 'post':
            return bitbucketServerHttp.postJson(apiUrl, options);
        case 'put':
            return bitbucketServerHttp.putJson(apiUrl, options);
        case 'patch':
            return bitbucketServerHttp.patchJson(apiUrl, options);
        case 'head':
            return bitbucketServerHttp.headJson(apiUrl, options);
        case 'delete':
            return bitbucketServerHttp.deleteJson(apiUrl, options);
        case 'get':
        default:
            return bitbucketServerHttp.getJson(apiUrl, options);
    }
}
async function accumulateValues(reqUrl, method = 'get', options, limit) {
    let accumulator = [];
    let nextUrl = addMaxLength(reqUrl, limit);
    while (typeof nextUrl !== 'undefined') {
        // TODO: fix typing (#9610)
        const { body } = await callApi(nextUrl, method, options);
        accumulator = [...accumulator, ...body.values];
        if (body.isLastPage !== false) {
            break;
        }
        const { search, ...parsedUrl } = url_1.default.parse(nextUrl, true);
        nextUrl = url_1.default.format({
            ...parsedUrl,
            query: {
                ...parsedUrl.query,
                start: body.nextPageStart,
            },
        });
    }
    return accumulator;
}
exports.accumulateValues = accumulateValues;
function isInvalidReviewersResponse(err) {
    const errors = err?.response?.body?.errors ?? [];
    return (errors.length > 0 &&
        errors.every((error) => error.exceptionName === exports.BITBUCKET_INVALID_REVIEWERS_EXCEPTION));
}
exports.isInvalidReviewersResponse = isInvalidReviewersResponse;
function getInvalidReviewers(err) {
    const errors = err?.response?.body?.errors ?? [];
    let invalidReviewers = [];
    for (const error of errors) {
        if (error.exceptionName === exports.BITBUCKET_INVALID_REVIEWERS_EXCEPTION) {
            invalidReviewers = invalidReviewers.concat(error.reviewerErrors
                ?.map(({ context }) => context)
                .filter(is_1.default.nonEmptyString) ?? []);
        }
    }
    return invalidReviewers;
}
exports.getInvalidReviewers = getInvalidReviewers;
function generateUrlFromEndpoint(defaultEndpoint, opts, repository) {
    const url = new URL(defaultEndpoint);
    const generatedUrl = git.getUrl({
        protocol: url.protocol,
        // TODO: types (#7154)
        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
        auth: `${opts.username}:${opts.password}`,
        host: `${url.host}${url.pathname}${
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        url.pathname.endsWith('/') ? '' : /* istanbul ignore next */ '/'}scm`,
        repository,
    });
    logger_1.logger.debug(`Using generated endpoint URL: ${generatedUrl}`);
    return generatedUrl;
}
function injectAuth(url, opts) {
    const repoUrl = (0, url_2.parseUrl)(url);
    if (!repoUrl) {
        logger_1.logger.debug(`Invalid url: ${url}`);
        throw new Error(error_messages_1.CONFIG_GIT_URL_UNAVAILABLE);
    }
    // TODO: null checks (#7154)
    repoUrl.username = opts.username;
    repoUrl.password = opts.password;
    return repoUrl.toString();
}
function getRepoGitUrl(repository, defaultEndpoint, gitUrl, info, opts) {
    if (gitUrl === 'ssh') {
        const sshUrl = info.links.clone?.find(({ name }) => name === 'ssh');
        if (sshUrl === undefined) {
            throw new Error(error_messages_1.CONFIG_GIT_URL_UNAVAILABLE);
        }
        logger_1.logger.debug(`Using ssh URL: ${sshUrl.href}`);
        return sshUrl.href;
    }
    let cloneUrl = info.links.clone?.find(({ name }) => name === 'http');
    if (cloneUrl) {
        // Inject auth into the API provided URL
        return injectAuth(cloneUrl.href, opts);
    }
    // Http access might be disabled, try to find ssh url in this case
    cloneUrl = info.links.clone?.find(({ name }) => name === 'ssh');
    if (gitUrl === 'endpoint' || !cloneUrl) {
        return generateUrlFromEndpoint(defaultEndpoint, opts, repository);
    }
    // SSH urls can be used directly
    return cloneUrl.href;
}
exports.getRepoGitUrl = getRepoGitUrl;
//# sourceMappingURL=utils.js.map