/*
 * Copyright 2017-2020 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 { i18n, inElectron, isNavResponse, isLink, isStringWithOptionalContentType } from '@kui-shell/core';
import usage from './usage';
const clientStrings = i18n('client', 'about');
const strings = i18n('plugin-core-support');
/** I would love to place this in a separate file. see https://github.com/microsoft/TypeScript/issues/25636 */
function defaultConfig() {
    return {
        productName: 'Kui Demo',
        version: '0.0.1',
        menus: [
            {
                Kui: {
                    modes: [
                        {
                            mode: 'about',
                            content: 'Welcome to Kui. This is a sample About configuration',
                            contentType: 'text/markdown'
                        },
                        { mode: 'version', contentFrom: 'version --full' }
                    ]
                }
            }
        ]
    };
}
// check if about's apiVersion and kind suffices NavResponse
const checkApiVersionAndKind = (apiVersion, kind) => {
    if (!isNavResponse({ apiVersion, kind })) {
        console.error('error in about.json:', apiVersion, kind);
        throw new Error('apiVersion or kind in about.json is not supported');
    }
};
/**
 * Here, we consult the client/config.d/name.json model.
 *
 * @return the product name
 *
 */
function getName() {
    return __awaiter(this, void 0, void 0, function* () {
        return import('@kui-shell/client/config.d/name.json')
            .catch(() => {
            console.log('using default product name');
            return defaultConfig();
        })
            .then(_ => _.productName);
    });
}
/**
 * Here, we consult the client/config.d/about.json model.
 *
 * @return a `NavResponse`
 *
 */
const getAbout = () => {
    return import('@kui-shell/client/config.d/about.json').then((_) => __awaiter(void 0, void 0, void 0, function* () {
        const _apiVersion = _['apiVersion'];
        const _kind = _['kind'];
        // Check apiVersion and kind for users. It's ok if users don't specify them.
        if (_apiVersion !== undefined || _kind !== undefined) {
            checkApiVersionAndKind(_apiVersion, _kind);
        }
        // inject Configure Menu
        const fullMenus = _.menus.slice(0);
        const configureMenu = {
            label: strings('Configure'),
            items: [{ mode: 'theme', contentFrom: 'themes' }]
        };
        const response = {
            apiVersion: _apiVersion || 'kui-shell/v1',
            kind: _kind || 'NavResponse',
            breadcrumbs: [{ label: yield getName() }],
            menus: fullMenus.concat([configureMenu]),
            links: _['links'] || []
        };
        return response;
    }));
};
// translate the labels of modes
const translateModesLabel = (modesFromAbout) => {
    return modesFromAbout.map((modeFromAbout) => {
        // translate the label
        const label = clientStrings(modeFromAbout.label || modeFromAbout.mode);
        if (isStringWithOptionalContentType(modeFromAbout)) {
            return Object.assign({}, modeFromAbout, {
                label,
                content: clientStrings(modeFromAbout.content) // translate content string
            });
        }
        else {
            return Object.assign({}, modeFromAbout, {
                label
            });
        }
    });
};
const aboutWindow = () => __awaiter(void 0, void 0, void 0, function* () {
    const { apiVersion, breadcrumbs, kind, menus, links } = yield getAbout();
    // translate the label of sidecar modes under each menu
    menus.forEach(menu => {
        menu.label = clientStrings(menu.label);
        menu.items = translateModesLabel(menu.items);
    });
    // translate the label of each navlink
    links.forEach(link => {
        if (isLink(link)) {
            link.label = clientStrings(link.label);
        }
        else {
            console.error('error in about.json', link);
            throw new Error('links in about.json is not supported');
        }
    });
    return {
        apiVersion,
        breadcrumbs,
        kind,
        menus,
        links
    };
});
/**
 * @return a Table that enumerates the full version information
 *
 */
function renderFullVersion(name, version) {
    const versionModel = process.versions;
    versionModel[name] = version;
    return {
        noSort: true,
        noEntityColors: true,
        header: {
            name: 'COMPONENT',
            attributes: [{ value: 'VERSION' }]
        },
        body: [name, 'electron', 'chrome', 'node', 'v8'].map((component, idx) => ({
            name: component,
            outerCSS: idx === 0 ? 'semi-bold' : '',
            css: idx === 0 ? 'cyan-text' : 'lighter-text',
            attributes: [{ key: 'VERSION', value: versionModel[component] }]
        }))
    };
}
/**
 * Report the current version
 *
 */
const reportVersion = ({ parsedOptions }) => __awaiter(void 0, void 0, void 0, function* () {
    const { version } = yield import('@kui-shell/client/package.json').catch(() => {
        console.log('using default version');
        return defaultConfig();
    });
    if (inElectron() && parsedOptions.full) {
        return renderFullVersion(yield getName(), version);
    }
    else {
        return version;
    }
});
/**
 * Here we install the command handlers for /version and /about
 *
 */
export default (commandTree) => {
    // special case, a bit of a hack for the OS-level About MenuItem;
    // see menu.ts in the core
    if (!commandTree) {
        return aboutWindow();
    }
    /**
     * Print out the current version of the tool, as text
     *
     */
    commandTree.listen('/version', // the command path
    reportVersion, // the command handler
    { usage: usage.version });
    /**
     * Open a graphical window displaying more detail about the tool
     *
     */
    commandTree.listen('/about', aboutWindow, {
        hidden: true // don't list about in the help menu
    });
    // getting started shortcut
    commandTree.listen('/getting/started', ({ REPL }) => REPL.qexec('about'));
};
//# sourceMappingURL=about.js.map