"use strict";

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

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

var _contexts = require("./contexts");

var _commandPrefix = _interopRequireDefault(require("../command-prefix"));

var _get = require("./get");

var _resource = require("../../lib/model/resource");

var _options = require("./options");

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

/*
 * Copyright 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());
  });
};

/**
 * Summarize the resources in the namespace indicated by the last
 * positional argument into a table, where resources are histogrammed
 * by kind.
 *
 */
function doSummarizeNamedNamespace(tab, ns) {
  return __awaiter(this, void 0, void 0, function* () {
    // otherwise, summarize resource count by kind in a table
    const response = yield tab.REPL.qexec(`kubectl get all -n ${ns} -o custom-columns=KIND:.kind`);
    const resources = response.body;
    const histogram = resources.reduce((M, {
      name: kind
    }) => {
      M[kind] = (M[kind] || 0) + 1;
      return M;
    }, {});
    const header = {
      name: 'KIND',
      attributes: [{
        key: 'COUNT',
        value: 'COUNT'
      }]
    };
    const body = Object.keys(histogram).map(kind => ({
      name: kind,
      onclick: `kubectl get ${kind} -n ${ns}`,
      attributes: [{
        key: 'COUNT',
        value: histogram[kind].toLocaleString()
      }]
    })).sort((a, b) => histogram[b.name] - histogram[a.name]); // sort be decreasing count

    return {
      header,
      body
    };
  });
}
/**
 * Summarize the resources in the namespace indicated by the last
 * positional argument into a table, where resources are histogrammed
 * by kind.
 *
 */


function doSummarizeNamespace(args) {
  // summarize this namespace
  const ns = args.argvNoOptions[args.argvNoOptions.length - 1];
  return doSummarizeNamedNamespace(args.tab, ns);
}
/**
 * @return the currently active namespace in the currently selected context
 *
 */


function doGetCurrentNamespace({
  tab
}) {
  return __awaiter(this, void 0, void 0, function* () {
    return (yield (0, _contexts.getCurrentContext)(tab)).metadata.namespace;
  });
}
/** Align the table model of outerCSS and css to CellShould hints */


function hintsFor(outerCSS, css) {
  const hints = [];

  if (/hide-with-sidecar/.test(outerCSS)) {
    hints.push("hide-with-sidecar"
    /* HideWithSidecar */
    );
  }

  if (/green-background/.test(css)) {
    hints.push("green-background"
    /* HaveGreenBadge */
    );
  } else if (/yellow-background/.test(css)) {
    hints.push("yellow-background"
    /* HaveYellowBadge */
    );
  } else if (/red-background/.test(css)) {
    hints.push("red-background"
    /* HaveRedBadge */
    );
  } else if (/gray-background/.test(css)) {
    hints.push("gray-background"
    /* HaveGrayBadge */
    );
  }

  return hints;
}
/** Convert old Table row model to new RadioTable row model. */


function t2rt({
  name,
  attributes
}) {
  return {
    nameIdx: 0,
    cells: [name, ...attributes.map(({
      value,
      outerCSS,
      css
    }) => ({
      value,
      hints: hintsFor(outerCSS, css)
    }))]
  };
}
/** SwitchFn impl that uses `kubectl config set-context` */


const doSwitchViaKubectl = (ns, args) => {
  return args.REPL.pexec(`kubectl config set-context --current --namespace=${ns}`);
};
/** Format as RadioTable */


function asRadioTable(doSwitch, args, {
  header,
  body
}) {
  return __awaiter(this, void 0, void 0, function* () {
    const {
      tab
    } = args;
    const {
      metadata: {
        namespace: currentNamespace
      }
    } = yield (0, _contexts.getCurrentContext)(tab);
    const defaultSelectedIdx = body.findIndex(_ => _.name === currentNamespace);
    const radio = {
      apiVersion: 'kui-shell/v1',
      kind: 'RadioTable',
      title: 'Namespaces',
      defaultSelectedIdx,
      header: t2rt(header),
      body: body.map(t2rt).map(rtRow => Object.assign(rtRow, {
        onSelect: () => {
          const ns = (0, _core.radioTableCellToString)(rtRow.cells[rtRow.nameIdx]);
          doSwitch(ns, args);
        }
      }))
    }; // place default at the top of the table, unless it is selected, in
    // which case the view will take care of things

    const rowIdxForDefaultNS = body.findIndex(_ => _.name === 'default');

    if (rowIdxForDefaultNS !== 0 && rowIdxForDefaultNS !== defaultSelectedIdx && body.length > 2) {
      const defaultRow = radio.body[rowIdxForDefaultNS];
      radio.body.splice(rowIdxForDefaultNS, 1); // delete the default row from body

      radio.body.splice(0, 0, defaultRow); // insert the default row at the top

      if (defaultSelectedIdx < rowIdxForDefaultNS) {
        radio.defaultSelectedIdx += 1;
      }
    }

    return radio;
  });
}
/** Table -> RadioTable view transformer */


function viewTransformer(doSwitch, args, response) {
  if ((0, _core.isTable)(response)) {
    if ((0, _options.isTableRequest)(args) && !(0, _options.isWatchRequest)(args)) {
      return asRadioTable(doSwitch, args, response);
    } else {
      return response;
    }
  } else if ((0, _resource.isKubeResource)(response)) {
    return (0, _get.doGetAsMMR)(args, response);
  } else {
    return response;
  }
}
/**
 * Command registration flags for commands that we want to present as
 * a RadioTable.
 *
 */


const rtFlags = Object.assign({}, _get.getFlags, {
  viewTransformer: viewTransformer.bind(undefined, doSwitchViaKubectl)
});

var _default = commandTree => {
  commandTree.listen(`/${_commandPrefix.default}/kubectl/get/namespaces`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/k/get/namespaces`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/kubectl/get/namespace`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/k/get/namespace`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/kubectl/get/ns`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/k/get/ns`, (0, _get.doGet)('kubectl'), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/namespace/current`, doGetCurrentNamespace, _get.getFlags);
  commandTree.listen(`/${_commandPrefix.default}/namespace/summarize`, doSummarizeNamespace, _get.getFlags);
};

exports.default = _default;