import JiraApi from "jira-client";
import { TicketProviderRoot } from "./ticketProviderRoot.js";
import c from "chalk";
import sortArray from "sort-array";
import { getBranchMarkdown, getOrgMarkdown } from "../utils/notifUtils.js";
import { extractRegexMatches, uxLog } from "../utils/index.js";
import { SfError } from "@salesforce/core";
import { getEnvVar } from "../../config/index.js";
export class JiraProvider extends TicketProviderRoot {
    jiraClient = null;
    constructor() {
        super();
        const jiraOptions = {
            protocol: "https",
            host: (getEnvVar("JIRA_HOST") || "").replace("https://", ""),
            apiVersion: "3",
            strictSSL: true,
        };
        // Basic Auth
        if (getEnvVar("JIRA_EMAIL") && getEnvVar("JIRA_TOKEN")) {
            jiraOptions.username = getEnvVar("JIRA_EMAIL") || "";
            jiraOptions.password = getEnvVar("JIRA_TOKEN") || "";
            this.isActive = true;
        }
        // Personal access token
        if (getEnvVar("JIRA_PAT")) {
            jiraOptions.bearer = getEnvVar("JIRA_PAT") || "";
            this.isActive = true;
        }
        if (this.isActive) {
            this.jiraClient = new JiraApi(jiraOptions);
        }
    }
    static isAvailable() {
        if (
        // Basic auth
        getEnvVar("JIRA_HOST") &&
            getEnvVar("JIRA_TOKEN") &&
            getEnvVar("JIRA_EMAIL")) {
            return true;
        }
        if (
        // Personal Access Token
        getEnvVar("JIRA_HOST") &&
            getEnvVar("JIRA_PAT")) {
            return true;
        }
        return false;
    }
    getLabel() {
        return "sfdx-hardis JIRA connector";
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static async getTicketsFromString(text, options = {}) {
        const tickets = [];
        // Extract JIRA tickets using URL references
        const jiraUrlRegex = /(https:\/\/.*(jira|atlassian\.net).*\/[A-Z0-9]+-\d+\b)/g;
        const jiraMatches = await extractRegexMatches(jiraUrlRegex, text);
        for (const jiraTicketUrl of jiraMatches) {
            const pattern = /https:\/\/.*\/([A-Z0-9]+-\d+\b)/;
            const match = jiraTicketUrl.match(pattern);
            if (match) {
                const ticketId = match[1];
                if (!tickets.some((ticket) => ticket.url === jiraTicketUrl || ticket.id === ticketId)) {
                    tickets.push({
                        provider: "JIRA",
                        url: jiraTicketUrl,
                        id: ticketId,
                    });
                }
            }
        }
        // Extract JIRA tickets using Identifiers
        const jiraBaseUrl = getEnvVar("JIRA_HOST") || "https://define.JIRA_HOST.in.cicd.variables/";
        const jiraRegex = getEnvVar("JIRA_TICKET_REGEX") || "(?<=[^a-zA-Z0-9_-]|^)([A-Za-z0-9]{2,10}-\\d{1,6})(?=[^a-zA-Z0-9_-]|$)";
        const jiraRefRegex = new RegExp(jiraRegex, "gm");
        const jiraRefs = await extractRegexMatches(jiraRefRegex, text);
        const jiraBaseUrlBrowse = jiraBaseUrl.replace(/\/$/, "") + "/browse/";
        for (const jiraRef of jiraRefs) {
            const jiraTicketUrl = jiraBaseUrlBrowse + jiraRef;
            if (!tickets.some((ticket) => ticket.url === jiraTicketUrl || ticket.id === jiraRef)) {
                tickets.push({
                    provider: "JIRA",
                    url: jiraTicketUrl,
                    id: jiraRef,
                });
            }
        }
        const ticketsSorted = sortArray(tickets, { by: ["id"], order: ["asc"] });
        return ticketsSorted;
    }
    async collectTicketsInfo(tickets) {
        const jiraTicketsNumber = tickets.filter((ticket) => ticket.provider === "JIRA").length;
        if (jiraTicketsNumber > 0) {
            uxLog("action", this, c.cyan(`[JiraProvider] Now trying to collect ${jiraTicketsNumber} tickets infos from JIRA server ` + process.env.JIRA_HOST + " ..."));
        }
        for (const ticket of tickets) {
            if (ticket.provider === "JIRA") {
                let ticketInfo = null;
                try {
                    ticketInfo = await this.jiraClient.getIssue(ticket.id);
                }
                catch (e) {
                    uxLog("warning", this, c.yellow(`[JiraApi] Error while trying to get ${ticket.id} information: ${e.message}`));
                }
                if (ticketInfo) {
                    const body = ticketInfo?.fields?.description?.content?.length > 0
                        ? ticketInfo.fields?.description?.content?.map((content) => content.text).join("\n")
                        : "";
                    ticket.foundOnServer = true;
                    ticket.subject = ticketInfo?.fields?.summary || "";
                    ticket.body = body;
                    ticket.status = ticketInfo.fields?.status?.id || "";
                    ticket.statusLabel = ticketInfo.fields?.status?.name || "";
                    if (ticket.subject === "") {
                        uxLog("warning", this, c.yellow("[JiraProvider] Unable to collect JIRA ticket info for " + ticket.id));
                        if (JSON.stringify(ticketInfo).includes("<!DOCTYPE html>")) {
                            uxLog("log", this, c.grey("[JiraProvider] This is probably a JIRA auth config issue, as HTML is returned"));
                        }
                        else {
                            uxLog("log", this, c.grey(JSON.stringify(ticketInfo)));
                        }
                        ticket.foundOnServer = false;
                    }
                    uxLog("log", this, c.grey("[JiraProvider] Collected data for ticket " + ticket.id));
                }
                else {
                    uxLog("warning", this, c.yellow("[JiraProvider] Unable to get JIRA issue " + ticket.id));
                }
            }
        }
        return tickets;
    }
    async postDeploymentComments(tickets, org, pullRequestInfo) {
        uxLog("action", this, c.cyan(`[JiraProvider] Try to post comments on ${tickets.length} tickets...`));
        const genericHtmlResponseError = "Probably config/access error since response is HTML";
        const orgMarkdown = JSON.parse(await getOrgMarkdown(org, "jira"));
        const branchMarkdown = JSON.parse(await getBranchMarkdown("jira"));
        const tag = await this.getDeploymentTag();
        const commentedTickets = [];
        const taggedTickets = [];
        for (const ticket of tickets) {
            if (ticket.foundOnServer) {
                // Build comment
                let prTitle = "";
                let prUrl = "";
                let prAuthor = "";
                if (pullRequestInfo) {
                    prUrl = pullRequestInfo.webUrl;
                    if (prUrl) {
                        prTitle = pullRequestInfo.title;
                        prAuthor = pullRequestInfo?.authorName;
                    }
                }
                const jiraComment = this.getJiraDeploymentCommentAdf(orgMarkdown.label, orgMarkdown.url, branchMarkdown.label, branchMarkdown.url || "", prTitle, prUrl, prAuthor);
                // Post comment
                try {
                    const commentPostRes = await this.jiraClient.addCommentAdvanced(ticket.id, { body: jiraComment });
                    if (JSON.stringify(commentPostRes).includes("<!DOCTYPE html>")) {
                        throw new SfError(genericHtmlResponseError);
                    }
                    commentedTickets.push(ticket);
                }
                catch (e6) {
                    uxLog("warning", this, c.yellow(`[JiraProvider] Error while posting comment on ${ticket.id}: ${e6.message}`));
                }
                // Add deployment label to JIRA ticket
                try {
                    const issueUpdate = {
                        update: {
                            labels: [{ add: tag }],
                        },
                    };
                    await this.jiraClient.updateIssue(ticket.id, issueUpdate);
                    taggedTickets.push(ticket);
                }
                catch (e6) {
                    if (e6.message != null && e6.message.includes("<!doctype html>")) {
                        e6.message = genericHtmlResponseError;
                    }
                    uxLog("warning", this, c.yellow(`[JiraProvider] Error while adding label ${tag} on ${ticket.id}: ${e6.message}`));
                }
            }
        }
        // Summary
        if (commentedTickets.length > 0 || taggedTickets.length > 0) {
            uxLog("log", this, c.grey(`[JiraProvider] Posted comments on ${commentedTickets.length} ticket(s): ` + commentedTickets.map((ticket) => ticket.id).join(", ")));
            uxLog("log", this, c.grey(`[JiraProvider] Added label ${tag} on ${taggedTickets.length} ticket(s): ` + taggedTickets.map((ticket) => ticket.id).join(", ")));
        }
        return tickets;
    }
    getJiraDeploymentCommentAdf(orgName, orgUrl, branchName, branchUrl, prTitle, prUrl, prAuthor) {
        const comment = {
            version: 1,
            type: "doc",
            content: [
                {
                    type: "paragraph",
                    content: [
                        {
                            type: "text",
                            text: "Deployed by ",
                        },
                        {
                            type: "text",
                            text: "sfdx-hardis",
                            marks: [
                                {
                                    type: "link",
                                    attrs: {
                                        href: "${CONSTANTS.DOC_URL_ROOT}/",
                                    },
                                },
                            ],
                        },
                        {
                            type: "text",
                            text: " in ",
                        },
                        {
                            type: "text",
                            text: orgName,
                            marks: [
                                {
                                    type: "link",
                                    attrs: {
                                        href: orgUrl,
                                    },
                                },
                                {
                                    type: "strong",
                                },
                            ],
                        },
                        {
                            type: "text",
                            text: " from branch ",
                        },
                        {
                            type: "text",
                            text: branchName,
                            marks: [
                                {
                                    type: "link",
                                    attrs: {
                                        href: branchUrl,
                                    },
                                },
                                {
                                    type: "strong",
                                },
                            ],
                        },
                    ],
                },
                {
                    type: "paragraph",
                    content: [
                        {
                            type: "text",
                            text: "Related PR: ",
                        },
                        {
                            type: "text",
                            text: prTitle,
                            marks: [
                                {
                                    type: "link",
                                    attrs: {
                                        href: prUrl,
                                    },
                                },
                            ],
                        },
                        {
                            type: "text",
                            text: `, by ${prAuthor}`,
                        },
                    ],
                },
            ],
        };
        return comment;
    }
}
//# sourceMappingURL=jiraProvider.js.map