"use strict";

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

var _debug = _interopRequireDefault(require("debug"));

var _child_process = require("child_process");

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

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

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

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

/*
 * Copyright 2019 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 debug = (0, _debug.default)('plugin-kubeui/controller/kubectl/raw');
/**
 * This is the final bottoming out of the exec/spawn of the native
 * executable.
 *
 */

const doNativeExec = args => new Promise((resolve, reject) => {
  const env = Object.assign({}, !(0, _core.inBrowser)() ? process.env : {}, args.execOptions.env);
  delete env.DEBUG;

  if ((args.parsedOptions.f || args.parsedOptions.filename) && typeof args.parsedOptions.f === 'string') {
    const filename = (0, _core.expandHomeDir)(args.parsedOptions.f || args.parsedOptions.filename);
    const idx = args.argv.indexOf(args.parsedOptions.f ? '-f' : '--filename');

    if (idx >= 0) {
      args.argv[idx + 1] = filename;
    }
  }

  const executable = args.argv[0].replace(/^_/, '');
  const child = (0, _child_process.spawn)(executable, args.argv.slice(1), {
    env
  }); // this is needed e.g. to handle ENOENT; otherwise the kui process may die with an uncaught exception

  child.on('error', err => {
    console.error(`error spawning ${executable}`, err);
    reject(err);
  });
  let stdout = '';
  child.stdout.on('data', data => {
    stdout += data.toString();
  });
  let stderr = '';
  child.stderr.on('data', data => {
    stderr += data.toString();
  });
  child.on('close', code => __awaiter(void 0, void 0, void 0, function* () {
    // debug('exec close', code)
    // debug('exec stdout', out)
    if (stderr.length > 0 || code !== 0) {
      debug('exec has stderr with code %s', code);
      debug('exec stderr command', args.command);
      debug('exec stderr', stderr);
    }

    const noResources = /no resources found/i.test(stderr);

    if (stdout.length === 0 && (code !== 0 || noResources)) {
      const message = stderr;
      const fileNotFound = /error: the path/.test(message);
      const codeForREPL = noResources || /not found/i.test(message) || /doesn't have/i.test(message) ? 404 : /already exists/i.test(message) ? 409 : fileNotFound ? 412 : 500;

      if (args.execOptions.failWithUsage) {
        reject(new Error(undefined));
      } else {
        const error = new Error(message);
        error.statusCode = code;
        error.code = codeForREPL;
        reject(error);
      }
    } else {
      resolve({
        content: {
          code,
          stdout,
          stderr,
          wasSentToPty: false
        }
      });
    }
  }));
});
/**
 * A convenience wrapper over `doNativeExec` that extracts only
 * stdout, and discards the exit code and stderr.
 *
 */


exports.doNativeExec = doNativeExec;

function doExecRaw(command, parsedOptions, execOptions) {
  return __awaiter(this, void 0, void 0, function* () {
    return (yield doNativeExec({
      command,
      argv: (0, _core.split)(command),
      parsedOptions,
      execOptions
    })).content.stdout;
  });
}

var _default = registrar => __awaiter(void 0, void 0, void 0, function* () {
  registrar.listen(`/${_commandPrefix.default}/_kubectl`, doNativeExec, Object.assign({}, _flags.default, {
    requiresLocal: true
  }));
});

exports.default = _default;