"use strict";
/*
 * Copyright © 2019 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.executeCancelGoalSets = void 0;
const string_1 = require("@atomist/automation-client/lib/internal/util/string");
const GraphClient_1 = require("@atomist/automation-client/lib/spi/graph/GraphClient");
const slack_messages_1 = require("@atomist/slack-messages");
const _ = require("lodash");
const Cancel_1 = require("../../api/goal/common/Cancel");
const Goals_1 = require("../../api/goal/Goals");
const types_1 = require("../../typings/types");
const fetchGoalsOnCommit_1 = require("../goal/fetchGoalsOnCommit");
const storeGoals_1 = require("../goal/storeGoals");
/**
 * Cancel any pending goals that are on the previous commit of the goal's branch
 * @param options
 * @param name
 */
function executeCancelGoalSets(options, name) {
    return async (gi) => {
        const { goalEvent } = gi;
        if (!goalEvent.push.before) {
            return {
                code: 0,
                description: `No goals canceled \u00B7 first push on branch`,
            };
        }
        const registration = gi.configuration.name;
        const optsToUse = Object.assign({ goalFilter: Cancel_1.DefaultCancelOptions.goalFilter }, options);
        const goals = await gi.context.graphClient.query({
            name: "SdmGoalByShaAndBranch",
            variables: {
                sha: goalEvent.push.before.sha,
                branch: goalEvent.branch,
                repo: goalEvent.repo.name,
                owner: goalEvent.repo.owner,
                providerId: goalEvent.repo.providerId,
                uniqueNames: _.uniq(_.flatten(optsToUse.goals.map(g => {
                    if (Goals_1.isGoals(g)) {
                        return g.goals.map(gg => gg.uniqueName);
                    }
                    else {
                        return g.uniqueName;
                    }
                }))),
                names: string_1.toStringArray(optsToUse.goalNames || []),
            },
            options: GraphClient_1.QueryNoCacheOptions,
        });
        if (goals && goals.SdmGoal && goals.SdmGoal.length > 0) {
            const currentGoals = fetchGoalsOnCommit_1.sumSdmGoalEvents(goals.SdmGoal);
            const cancelableGoals = currentGoals.filter(g => provenanceFilter(g, registration))
                .filter(g => optsToUse.goalFilter(g));
            if (cancelableGoals.length > 0) {
                const canceledGoalSets = _.uniq(cancelableGoals.map(g => g.goalSetId));
                for (const goal of cancelableGoals) {
                    gi.progressLog.write(`Canceling goal '${goal.name} (${goal.uniqueName})' in state '${goal.state}' of goal set '${goal.goalSet} - ${goal.goalSetId}'`);
                    const updatedGoal = _.cloneDeep(goal);
                    updatedGoal.ts = Date.now();
                    updatedGoal.version = updatedGoal.version + 1;
                    updatedGoal.state = types_1.SdmGoalState.canceled;
                    updatedGoal.description = `Canceled ${goal.name}`;
                    const actx = gi.context;
                    const prov = {
                        name,
                        registration: actx.context.name,
                        version: actx.context.version,
                        correlationId: actx.context.correlationId,
                        ts: Date.now(),
                    };
                    updatedGoal.provenance.push(prov);
                    await storeGoals_1.storeGoal(gi.context, updatedGoal);
                }
                return {
                    code: 0,
                    description: `Canceled goals ${canceledGoalSets.map(gs => slack_messages_1.codeLine(gs.slice(0, 7))).join(", ")}`,
                };
            }
        }
        return undefined;
    };
}
exports.executeCancelGoalSets = executeCancelGoalSets;
function provenanceFilter(sdmGoal, registration) {
    const provenances = [...sdmGoal.provenance].sort((p1, p2) => p1.ts - p2.ts);
    return provenances[0].registration === registration || registration.startsWith(`${provenances[0].registration}-job`);
}
//# sourceMappingURL=executeCancel.js.map