"use strict";

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

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

var _flags = _interopRequireDefault(require("./flags"));

var _apiVersion = _interopRequireDefault(require("./apiVersion"));

var _getNamespaces = require("./get-namespaces");

var _exec = require("./exec");

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

var _help = require("../../lib/util/help");

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

/*
 * 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 = 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 strings = (0, _core.i18n)('plugin-kubectl');
const usage = {
  context: command => ({
    command,
    strict: command,
    docs: 'Print your current kubernetes context',
    example: 'kubectl context'
  }),
  contexts: command => ({
    command,
    strict: command,
    docs: 'List your available kubernetes contexts',
    example: 'kubectl contexts'
  })
};
/** Exclude the CURRENT column. */

function rtRowsFor(row) {
  const rtRow = (0, _getNamespaces.t2rt)(row);
  rtRow.cells = rtRow.cells.slice(1);
  return rtRow;
}
/**
 * Add click handlers to change context
 *
 */


const asRadioTable = ({
  REPL
}, {
  header,
  body
}) => {
  /* const header = t2rt(table.header)
  const body = table.body.map(row => {
    const nameAttr = row.attributes.find(({ key }) => key === 'NAME')
    const { value: contextName } = nameAttr
       return {
      nameIdx: 0,
      cells: [
        contextName,
        ...row.attributes.map(({ value, outerCSS, css }) => ({
          value,
          hints: hintsFor(outerCSS, css),
          onSelect: () => REPL.pexec(`kubectl config use-context ${REPL.encodeComponent(contextName)}`)
        }))
      ]
    }
  }) */
  // leftover from old model bad choices
  const defaultSelectedIdx = body.findIndex(_ => _.rowCSS[0] === 'selected-row');
  return {
    apiVersion: 'kui-shell/v1',
    kind: 'RadioTable',
    title: strings('contextsTableTitle'),
    defaultSelectedIdx,
    header: rtRowsFor(header),
    body: body.map(row => rtRowsFor(row)).map(rtRow => Object.assign(rtRow, {
      onSelect: () => __awaiter(void 0, void 0, void 0, function* () {
        const context = (0, _core.radioTableCellToString)(rtRow.cells[rtRow.nameIdx]);
        yield REPL.pexec(`kubectl config use-context ${context}`);
      })
    }))
  };
};

function valueOf(key, row) {
  const cell = row.attributes.find(_ => _.key === key);
  return cell ? cell.value : '';
}
/**
 * @return a `KubeContext` representing the current context
 *
 */


function getCurrentContext({
  REPL
}) {
  return __awaiter(this, void 0, void 0, function* () {
    // fetch both the current context name, and the list of KubeContext objects */
    const [currentContextName, {
      content: contexts
    }] = yield Promise.all([REPL.qexec(`context`), REPL.rexec(`contexts`)]); // the KubeContext object matching the current context name

    return contexts.find(_ => _.metadata.name === currentContextName);
  });
}

function getCurrentContextName({
  REPL
}) {
  return __awaiter(this, void 0, void 0, function* () {
    const context = yield REPL.qexec('kubectl config current-context');
    return context ? context.trim() : context;
  });
}
/** Extract the namespace from the current context */


function getCurrentDefaultNamespace({
  REPL
}) {
  return __awaiter(this, void 0, void 0, function* () {
    const ns = yield REPL.qexec(`kubectl config view --minify --output "jsonpath={..namespace}"`).catch(err => {
      console.error('error determining default namespace', err);
      return 'default';
    });

    if (typeof ns !== 'string') {
      // e.g. microk8s
      return 'default';
    } else {
      return ns ? ns.trim() : ns;
    }
  });
}
/**
 * List contets command handler
 *
 */


const listContexts = args => __awaiter(void 0, void 0, void 0, function* () {
  const execOptions = Object.assign({}, args.execOptions, {
    render: false
  });
  const contexts = yield args.REPL.qexec(`kubectl config get-contexts`, undefined, undefined, execOptions);

  if (args.execOptions.raw) {
    return {
      mode: 'raw',
      content: contexts.body.map(_ => ({
        apiVersion: _apiVersion.default,
        kind: 'Context',
        originatingCommand: args.command,
        isKubeResource: true,
        metadata: {
          name: valueOf('NAME', _),
          namespace: valueOf('NAMESPACE', _)
        },
        spec: {
          user: valueOf('AUTHINFO', _),
          cluster: valueOf('CLUSTER', _)
        }
      }))
    };
  } else {
    return contexts;
  }
}); // addClickHandlers(contexts, args)

/** Table -> RadioTable view transformer */


function viewTransformer(args, response) {
  if ((0, _core.isTable)(response)) {
    return asRadioTable(args, response);
  } else {
    return response;
  }
}
/**
 * Command registration flags for commands that we want to present as
 * a RadioTable.
 *
 */


const rtFlags = Object.assign({}, _flags.default, {
  viewTransformer
});
/**
 * Register the commands
 *
 */

var _default = commandTree => {
  commandTree.listen(`/${_commandPrefix.default}/kubectl/config/get-contexts`, args => (0, _help.isUsage)(args) ? (0, _help.doHelp)('kubectl', args) : (0, _exec.doExecWithTable)(args), rtFlags);
  commandTree.listen(`/${_commandPrefix.default}/context`, ({
    REPL
  }) => __awaiter(void 0, void 0, void 0, function* () {
    return (yield REPL.qexec('kubectl config current-context')).trim();
  }), Object.assign({
    usage: usage.context('context')
  }, _flags.default));
  commandTree.listen(`/${_commandPrefix.default}/contexts`, listContexts, Object.assign({
    usage: usage.contexts('contexts')
  }, rtFlags));
};

exports.default = _default;