"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OctokitGitHubLinkedBranchService = void 0;
exports.createLinkedBranchService = createLinkedBranchService;
const octokit_loader_1 = require("../github/octokit-loader");
const project_ref_1 = require("../github/project-ref");
const constants_1 = require("./constants");
async function createLinkedBranchService(config, authProvider) {
    if (config.repositoryHost.kind !== "github" ||
        config.ticketTracker.kind !== "github" ||
        typeof authProvider.getRepositoryHostToken !== "function") {
        return createNoopLinkedBranchService();
    }
    const token = await authProvider.getRepositoryHostToken(config.repositoryHost);
    const octokit = await (0, octokit_loader_1.createGitHubOctokit)({ auth: token });
    return new OctokitGitHubLinkedBranchService(octokit, (0, project_ref_1.parseGitHubProjectRef)(config.repositoryHost.projectRef));
}
class OctokitGitHubLinkedBranchService {
    octokit;
    project;
    constructor(octokit, project) {
        this.octokit = octokit;
        this.project = project;
    }
    async ensureLinkedBranch(input) {
        const result = await this.octokit.graphql(GITHUB_LINKED_BRANCH_LOOKUP_QUERY, {
            owner: this.project.owner,
            repo: this.project.repo,
            issueNumber: Number(input.issueId),
            baseBranchQualifiedName: toQualifiedRefName(input.baseBranch),
        });
        const existingLinkedBranch = result.repository.issue.linkedBranches.nodes.find((linkedBranch) => linkedBranch?.ref?.name === input.branchName);
        if (existingLinkedBranch) {
            return;
        }
        await this.octokit.graphql(GITHUB_CREATE_LINKED_BRANCH_MUTATION, {
            input: {
                issueId: result.repository.issue.id,
                name: input.branchName,
                oid: result.repository.baseBranch.target.oid,
                repositoryId: result.repository.id,
            },
        });
    }
}
exports.OctokitGitHubLinkedBranchService = OctokitGitHubLinkedBranchService;
function createNoopLinkedBranchService() {
    return {
        async ensureLinkedBranch() { },
    };
}
function toQualifiedRefName(branchName) {
    return branchName.startsWith("refs/")
        ? branchName
        : `refs/heads/${branchName}`;
}
const GITHUB_LINKED_BRANCH_LOOKUP_QUERY = `
  query GitHubLinkedBranchLookup(
    $owner: String!
    $repo: String!
    $issueNumber: Int!
    $baseBranchQualifiedName: String!
  ) {
    repository(owner: $owner, name: $repo) {
      id
      issue(number: $issueNumber) {
        id
        linkedBranches(first: ${constants_1.REPOSITORY_HOST_PROVIDER_PAGE_LIMIT}) {
          nodes {
            ref {
              name
            }
          }
        }
      }
      baseBranch: ref(qualifiedName: $baseBranchQualifiedName) {
        target {
          ... on Commit {
            oid
          }
        }
      }
    }
  }
`;
const GITHUB_CREATE_LINKED_BRANCH_MUTATION = `
  mutation GitHubCreateLinkedBranch($input: CreateLinkedBranchInput!) {
    createLinkedBranch(input: $input) {
      linkedBranch {
        id
      }
    }
  }
`;
