"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _core = require("@kui-shell/core");

var _usage = _interopRequireDefault(require("./usage"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/*
 * 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 = void 0 && (void 0).__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());
  });
};

const clientStrings = (0, _core.i18n)('client', 'about');
const strings = (0, _core.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 (!(0, _core.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 Promise.resolve().then(() => require('@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 Promise.resolve().then(() => require('@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 ((0, _core.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 ((0, _core.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 Promise.resolve().then(() => require('@kui-shell/client/package.json')).catch(() => {
    console.log('using default version');
    return defaultConfig();
  });

  if ((0, _core.inElectron)() && parsedOptions.full) {
    return renderFullVersion(yield getName(), version);
  } else {
    return version;
  }
});
/**
 * Here we install the command handlers for /version and /about
 *
 */


var _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.default.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'));
};

exports.default = _default;