/*
 * Copyright 2018-19 IBM Corporation
 *
 * 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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import Debug from 'debug';
import { i18n } from '@kui-shell/core';
import { isUsage, doHelp, preprocessTable, formatTable } from '@kui-shell/plugin-kubectl';
import doExecWithStdout from './exec';
import commandPrefix from '../command-prefix';
const strings = i18n('plugin-kubectl');
const strings2 = i18n('plugin-kubectl', 'helm');
const debug = Debug('plugin-kubectl/helm/controller/helm/status');
/**
 * Format the output of a helm status command
 *
 */
export const format = (name, args, response, execOptions) => __awaiter(void 0, void 0, void 0, function* () {
    const command = 'kubectl';
    const verb = 'get';
    debug('nested?', execOptions.nested);
    debug('command', command);
    debug('verb', verb);
    const [headerString, resourcesString, notesString] = response.split(/RESOURCES:|(?=NOTES:)/);
    const namespaceMatch = response.match(/^NAMESPACE:\s+(.*)$/m) || [];
    const namespaceFromHelmStatusOutput = namespaceMatch[1];
    debug('namespace', namespaceFromHelmStatusOutput);
    // const namespaceFor = (entityType: string) => {
    const namespaceFor = () => {
        return namespaceFromHelmStatusOutput;
    };
    const resources = resourcesString
        .split(/==>/)
        .map(_ => _.split(/[\n\r]/))
        .filter(A => A.length > 0 && A[0])
        .map(A => {
        const kind = A[0].trim();
        // "v1/pod(related)" => "pod"
        const entityType = kind.replace(/(v\w+\/)?([^()]*)(\s*\(.*\))?/, '$2');
        if (!/\s*NAME(\s+|$)/.test(A[1])) {
            // no header row? this seems to be a bug in helm
            const match = A[1].match(/(.+\s+)(.+)/);
            if (match && match[1]) {
                const secondColIdx = match[1].length;
                const firstCol = 'NAME';
                const secondCol = 'AGE';
                const spaces = (nSpaces) => new Array(nSpaces).join(' ');
                const header = `${firstCol}${spaces(secondColIdx - firstCol.length)}${secondCol}`;
                A.splice(1, 0, header);
            }
        }
        return {
            kind,
            table: formatTable(command, verb, entityType, Object.assign({}, args, {
                parsedOptions: Object.assign({}, args.parsedOptions, { namespace: namespaceFor() })
            }), preprocessTable([A.slice(1).join('\n')])[0])
        };
    });
    debug('resources', resources);
    if (execOptions.nested) {
        debug('returning tables for nested call');
        return Promise.all(resources.map(({ kind, table }) => __awaiter(void 0, void 0, void 0, function* () {
            const T = yield table;
            T.title = kind;
            return T;
        })));
    }
    else {
        const notesMatch = notesString &&
            notesString.match(/^NOTES:\n(\S+) can be accessed via port (\d+) on the following DNS name from within your cluster:\n(\S+)([s\S]+)?/);
        const statusMatch = headerString.match(/LAST DEPLOYED: (.*)\nNAMESPACE: (.*)\nSTATUS: (.*)/);
        const status = !statusMatch
            ? headerString
            : `### ${strings2('Last Deployed')}
${statusMatch[1]}

### ${strings2('Namespace')}
${statusMatch[2]}

### ${strings('status')}
\`${statusMatch[3]}\`
`;
        const summary = !notesMatch
            ? notesString
            : `### Chart Name
${notesMatch[1]}

### Port
\`${notesMatch[2]}\`

### DNS Name
${notesMatch[3]}`;
        const notes = notesMatch && notesMatch[4];
        const overviewMenu = {
            label: 'Overview',
            items: [
                {
                    mode: 'status',
                    label: strings('status'),
                    content: status,
                    contentType: 'text/markdown'
                }
            ]
                .concat(!summary
                ? []
                : [
                    {
                        mode: 'summary',
                        label: strings('summary'),
                        content: summary,
                        contentType: 'text/markdown'
                    }
                ])
                .concat(!notes
                ? []
                : [
                    {
                        mode: 'notes',
                        label: strings2('Notes'),
                        content: notes,
                        contentType: 'text/markdown'
                    }
                ])
        };
        const resourcesMenu = {
            label: 'Resources',
            items: yield Promise.all(resources.map((_) => __awaiter(void 0, void 0, void 0, function* () {
                return ({
                    mode: _.kind,
                    content: yield _.table
                });
            })))
        };
        const response = {
            apiVersion: 'kui-shell/v1',
            kind: 'NavResponse',
            breadcrumbs: [{ label: 'helm' }, { label: 'release', command: `helm ls` }, { label: name }],
            menus: [overviewMenu, resourcesMenu]
        };
        return response;
    }
});
function doStatus(args) {
    return __awaiter(this, void 0, void 0, function* () {
        if (isUsage(args)) {
            return doHelp('helm', args);
        }
        const name = args.argvNoOptions[args.argvNoOptions.indexOf('status') + 1];
        const response = yield doExecWithStdout(args);
        try {
            return format(name, args, response, args.execOptions);
        }
        catch (err) {
            console.error('error formatting status', err);
            return response;
        }
    });
}
export default (registrar) => {
    registrar.listen(`/${commandPrefix}/helm/status`, doStatus);
};
//# sourceMappingURL=status.js.map