"use strict";
/*
 * Copyright © 2020 Atomist, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPushImpactListenerInvocation = void 0;
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const addressChannels_1 = require("../../api/context/addressChannels");
const skillContext_1 = require("../../api/context/skillContext");
const filesChangedSince_1 = require("../misc/git/filesChangedSince");
const filteredView_1 = require("../misc/project/filteredView");
/**
 * Create a PushImpactListenerInvocation from the given context.
 * Includes both the complete project and the changed files.
 * @param {GoalInvocation} goalInvocation
 * @param {GitProject} project
 * @return {Promise<PushImpactListenerInvocation>}
 */
async function createPushImpactListenerInvocation(goalInvocation, project) {
    const { goalEvent, credentials, id, context, addressChannels, preferences, configuration } = goalInvocation;
    const smartContext = teachToRespondInEventHandler(context, ...addressChannels_1.messageDestinationsFor(goalEvent.push.repo, context));
    const push = goalEvent.push;
    const filesChanged = await filesChangedSince_1.filesChangedSince(project, push);
    const impactedSubProject = !filesChanged ? project : filteredView_1.filteredView(project, path => filesChanged.includes(path));
    return {
        id,
        context: smartContext,
        configuration,
        addressChannels,
        preferences,
        project,
        impactedSubProject,
        credentials,
        filesChanged,
        commit: goalEvent.push.after,
        push,
        skill: skillContext_1.createSkillContext(context),
    };
}
exports.createPushImpactListenerInvocation = createPushImpactListenerInvocation;
/**
 * Safely mutate the given HandlerContext so that it can respond even when used in
 * an EventHandler
 * @param ctx context to wrap
 * @param destinations
 * @return {HandlerContext}
 */
function teachToRespondInEventHandler(ctx, ...destinations) {
    const oldRespondMethod = ctx.messageClient.respond;
    ctx.messageClient.respond = async (msg, options) => {
        // First try routing to response. If that doesn't work, we're probably
        // in an event handler. Try linked channels.
        try {
            return await oldRespondMethod(msg, options);
        }
        catch (err) {
            logger_1.logger.debug("Rerouting response message to destinations: message was [%s]", msg);
            return ctx.messageClient.send(msg, destinations, options);
        }
    };
    return ctx;
}
//# sourceMappingURL=createPushImpactListenerInvocation.js.map