"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.
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.kubernetesUndeploy = exports.KubernetesUndeployParameters = void 0;
const decorators_1 = require("@atomist/automation-client/lib/decorators");
const logger_1 = require("@atomist/automation-client/lib/util/logger");
const _ = require("lodash");
const messages_1 = require("../../../api-helper/misc/slack/messages");
const application_1 = require("../kubernetes/application");
const name_1 = require("../support/name");
const namespace_1 = require("../support/namespace");
const application_2 = require("../sync/application");
let KubernetesUndeployParameters = class KubernetesUndeployParameters {
    constructor() {
        this.ns = namespace_1.K8sDefaultNamespace;
    }
};
__decorate([
    decorators_1.Parameter({
        displayName: "Name",
        description: "name of resources to remove",
        pattern: /^[a-z](?:[-a-z0-9]*[a-z0-9])?$/,
        validInput: "a valid Kubernetes resource name, beginning with a lowercase letter, ending with a lowercase" +
            "letter or number, and containing only lowercase letters, numbers, and dashes (-)",
        minLength: 1,
        maxLength: 63,
        required: true,
    }),
    __metadata("design:type", String)
], KubernetesUndeployParameters.prototype, "name", void 0);
__decorate([
    decorators_1.Parameter({
        displayName: "Namespace",
        description: "namespace of resources to remove",
        pattern: /^[a-z](?:[-a-z0-9]*[a-z0-9])?$/,
        validInput: "a valid Kubernetes namespace, beginning with a lowercase letter, ending with a lowercase" +
            "letter or number, and containing only lowercase letters, numbers, and dashes (-)",
        minLength: 1,
        maxLength: 63,
        required: false,
    }),
    __metadata("design:type", String)
], KubernetesUndeployParameters.prototype, "ns", void 0);
KubernetesUndeployParameters = __decorate([
    decorators_1.Parameters()
], KubernetesUndeployParameters);
exports.KubernetesUndeployParameters = KubernetesUndeployParameters;
/**
 * Safely remove all resources related to a Kubernetes application.
 *
 * If the SDM configuration says this packs commands should be added,
 * i.e., `sdm.configuration.sdm.k8s.options.addCommands` is `true`,
 * the command will have the intent `kube undeploy SDM_NAME`.
 * Otherwise the command will be registered without an intent.
 */
function kubernetesUndeploy(sdm) {
    const cmd = {
        name: "KubernetesUndeploy",
        description: "remove all resources related to an application from Kubernetes cluster",
        paramsMaker: KubernetesUndeployParameters,
        listener: kubeUndeploy,
    };
    if (_.get(sdm, "configuration.sdm.k8s.options.addCommands", false)) {
        cmd.intent = `kube undeploy ${name_1.cleanName(sdm.configuration.name)}`;
    }
    return cmd;
}
exports.kubernetesUndeploy = kubernetesUndeploy;
/**
 * Delete an application from a Kubernetes cluster.  If any of the
 * application resources do not exist in the cluster, they are
 * ignored.  In other words, it is not an error to try to delete
 * something that does not exist.  If a sync repo is configured, the
 * corresponding resource specs are deleted from the sync repo.
 */
async function kubeUndeploy(ci) {
    const slug = `${ci.parameters.ns}/${ci.parameters.name}`;
    const delApp = {
        name: ci.parameters.name,
        ns: ci.parameters.ns,
        workspaceId: ci.context.workspaceId,
    };
    const result = {
        code: 0,
        message: `Successfully deleted ${slug} resources from Kubernetes`,
    };
    try {
        const deleted = await application_1.deleteApplication(delApp);
        logger_1.logger.info(result.message);
        try {
            await application_2.syncApplication(delApp, deleted, "delete");
        }
        catch (err) {
            result.code++;
            const msg = `Failed to delete resource specs from sync repo: ${err.message}`;
            logger_1.logger.error(msg);
            result.message = `${result.message} but ${msg}`;
        }
        try {
            await ci.context.messageClient.respond(messages_1.slackSuccessMessage("Kubernetes Undeploy", result.message));
        }
        catch (err) {
            const msg = `Failed to send response message: ${err.message}`;
            logger_1.logger.error(msg);
            result.message = `${result.message} but ${msg}`;
        }
    }
    catch (e) {
        result.code++;
        result.message = `Failed to delete all ${slug} resources from Kubernetes: ${e.message}`;
        logger_1.logger.error(result.message);
        try {
            await ci.context.messageClient.respond(result.message);
        }
        catch (err) {
            result.code++;
            result.message = `${result.message}; Failed to send response message: ${err.message}`;
            logger_1.logger.error(result.message);
        }
    }
    return result;
}
//# sourceMappingURL=kubernetesUndeploy.js.map