"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createScopedRepositoryHostClient = createScopedRepositoryHostClient;
const promise_cache_1 = require("../promise-cache");
function createScopedRepositoryHostClient(baseClient) {
    return new DefaultScopedRepositoryHostClient(baseClient);
}
class DefaultScopedRepositoryHostClient {
    baseClient;
    repositoryCache = {
        current: null,
    };
    pullRequestByBranchCache = new Map();
    automationStateByPullRequestNumberCache = new Map();
    pullRequestByNumberCache = new Map();
    pullRequestFilesByNumberCache = new Map();
    pullRequestCommitsByNumberCache = new Map();
    pullRequestNumberToBranch = new Map();
    constructor(baseClient) {
        this.baseClient = baseClient;
    }
    async getRepository() {
        return (0, promise_cache_1.getOrLoadPromiseCacheSlot)(this.repositoryCache, () => this.baseClient.getRepository());
    }
    async findPullRequestByBranch(branchName) {
        return (0, promise_cache_1.getOrLoadPromiseCacheEntry)(this.pullRequestByBranchCache, branchName, async () => {
            const pullRequest = await this.baseClient.findPullRequestByBranch(branchName);
            if (pullRequest) {
                this.pullRequestNumberToBranch.set(pullRequest.number, branchName);
            }
            return pullRequest;
        });
    }
    async getPullRequestAutomationState(pullRequestNumber) {
        return (0, promise_cache_1.getOrLoadPromiseCacheEntry)(this.automationStateByPullRequestNumberCache, pullRequestNumber, () => this.baseClient.getPullRequestAutomationState(pullRequestNumber));
    }
    async getPullRequest(pullRequestNumber) {
        return (0, promise_cache_1.getOrLoadPromiseCacheEntry)(this.pullRequestByNumberCache, pullRequestNumber, async () => {
            const pullRequest = await this.baseClient.getPullRequest(pullRequestNumber);
            if (pullRequest) {
                this.pullRequestNumberToBranch.set(pullRequest.number, pullRequest.headBranch);
            }
            return pullRequest;
        });
    }
    async listPullRequestChangedFiles(pullRequestNumber) {
        return (0, promise_cache_1.getOrLoadPromiseCacheEntry)(this.pullRequestFilesByNumberCache, pullRequestNumber, () => this.baseClient.listPullRequestChangedFiles(pullRequestNumber));
    }
    async listPullRequestCommits(pullRequestNumber) {
        return (0, promise_cache_1.getOrLoadPromiseCacheEntry)(this.pullRequestCommitsByNumberCache, pullRequestNumber, () => this.baseClient.listPullRequestCommits(pullRequestNumber));
    }
    async createPullRequest(input) {
        const pullRequest = await this.baseClient.createPullRequest(input);
        this.pullRequestNumberToBranch.set(pullRequest.number, input.headBranch);
        this.pullRequestByBranchCache.set(input.headBranch, Promise.resolve(pullRequest));
        this.pullRequestByNumberCache.set(pullRequest.number, Promise.resolve(pullRequest));
        this.automationStateByPullRequestNumberCache.delete(pullRequest.number);
        return pullRequest;
    }
    async mergePullRequest(pullRequestNumber, method) {
        await this.baseClient.mergePullRequest(pullRequestNumber, method);
        this.invalidatePullRequest(pullRequestNumber);
    }
    async isPullRequestHeadIncludedInBase(pullRequestNumber) {
        return this.baseClient.isPullRequestHeadIncludedInBase(pullRequestNumber);
    }
    async syncPullRequestAssignees(pullRequestNumber, assignees) {
        await this.baseClient.syncPullRequestAssignees(pullRequestNumber, assignees);
    }
    async syncPullRequestReviewers(pullRequestNumber, reviewers) {
        return this.baseClient.syncPullRequestReviewers(pullRequestNumber, reviewers);
    }
    async markPullRequestReadyForReview(pullRequestNumber) {
        await this.baseClient.markPullRequestReadyForReview(pullRequestNumber);
        this.invalidatePullRequest(pullRequestNumber);
    }
    invalidatePullRequest(pullRequestNumber) {
        this.automationStateByPullRequestNumberCache.delete(pullRequestNumber);
        this.pullRequestByNumberCache.delete(pullRequestNumber);
        this.pullRequestFilesByNumberCache.delete(pullRequestNumber);
        this.pullRequestCommitsByNumberCache.delete(pullRequestNumber);
        const branchName = this.pullRequestNumberToBranch.get(pullRequestNumber);
        if (branchName) {
            this.pullRequestByBranchCache.delete(branchName);
        }
    }
}
