"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = onKeyDown;
exports.setCaretPositionToLineStart = void 0;
var _debug = _interopRequireDefault(require("debug"));
var _Keys = require("@kui-shell/core/mdist/api/Keys");
var _Events = require("@kui-shell/core/mdist/api/Events");
var _Internal = require("@kui-shell/core/mdist/api/Internal");
var _Capabilities = require("@kui-shell/core/mdist/api/Capabilities");
var _Input = require("./Input");
var _TabCompletion = _interopRequireDefault(require("./TabCompletion"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
 * Copyright 2017 The Kubernetes Authors
 *
 * 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)('Terminal/Block/OnKeyDown');
function isMSIEControl(ctrl) {
  return Object.prototype.hasOwnProperty.call(ctrl, 'createTextRange');
}
/**
 * Update the caret position in an html INPUT field
 *
 */
const setCaretPosition = (ctrl, pos) => {
  if (ctrl.setSelectionRange) {
    ctrl.focus();
    ctrl.setSelectionRange(pos, pos);
  } else if (isMSIEControl(ctrl)) {
    const range = ctrl.createTextRange();
    range.collapse(true);
    range.moveEnd('character', pos);
    range.moveStart('character', pos);
    range.select();
  }
};
const setCaretPositionToStart = input => setCaretPosition(input, 0);
const setCaretPositionToEnd = input => setCaretPosition(input, input.value.length);
const setCaretPositionToLineStart = input => setCaretPosition(input, input.selectionStart);
/** Update the given input to reflect the given HistoryLine */
exports.setCaretPositionToLineStart = setCaretPositionToLineStart;
const updateInputAndMoveCaretToEOL = (input, entry) => {
  if (entry) {
    input.state.prompt.value = entry.raw;
    setTimeout(() => setCaretPositionToEnd(input.state.prompt), 0);
  } else {
    input.state.prompt.value = '';
  }
};
/**
 *
 * "hello wor<userHitsCtrl+Delete>" -> "hello "
 * "hello world <userHitsCtrl+Delete>" -> "hello world"
 * "hello.world<userHitsCtrl+Delete>" -> "hello"
 *
 */
function deleteThisWord(prompt) {
  const start = prompt.selectionStart;
  const end = prompt.selectionEnd;
  if (start === end) {
    let idx = start;
    for (; idx >= 0; idx--) {
      if (/\W/.test(prompt.value[idx])) {
        break;
      }
    }
    idx++; // back up the last idx--
    if (idx < start) {
      // another +1 here because the browser will delete one for us
      prompt.value = prompt.value.substring(0, idx + 1);
      return true;
    }
  }
  return false;
}
function onKeyDown(event) {
  const tab = (0, _Internal.splitFor)(this.props.tab);
  const block = this.props._block;
  const prompt = this.state.prompt;
  const char = event.keyCode;
  if (this.state.tabCompletion) {
    this.state.tabCompletion.key(event);
    return;
  } else if (event.key === 'Tab') {
    (0, _TabCompletion.default)(this, event);
  }
  if (event.key === 'Backspace' && event.ctrlKey) {
    deleteThisWord(prompt);
  } else if (char === _Keys.KeyCodes.C && event.ctrlKey) {
    // block could be undefined for bottom-input mode
    if (block) {
      // Ctrl+C, cancel
      (0, _Internal.doCancel)(tab, block, prompt.value);
    }
  } else if (char === _Keys.KeyCodes.U && event.ctrlKey) {
    // clear line
    prompt.value = '';
  } else if (event.key === 'Home' && event.shiftKey && process.platform === 'darwin') {
    // go to beginning of line
    setCaretPositionToStart(prompt);
  } else if (event.key === 'End' && event.shiftKey && process.platform === 'darwin') {
    // go to end of line
    setCaretPositionToEnd(prompt);
  }
  // keydown handler for HTMLInputElement
  if ((0, _Input.isHTMLInputElement)(this.state.prompt)) {
    if (char === _Keys.KeyCodes.UP || char === _Keys.KeyCodes.P && event.ctrlKey) {
      // go to previous command in history
      setTimeout(() => __awaiter(this, void 0, void 0, function* () {
        const historyModel = yield (yield Promise.resolve().then(() => require('@kui-shell/core/mdist/api/History'))).History(tab);
        const entry = historyModel.previous();
        if (entry) {
          updateInputAndMoveCaretToEOL(this, entry);
        }
      }));
    } else if (char === _Keys.KeyCodes.D && event.ctrlKey) {
      if (prompt.value === '') {
        // <-- only if the line is blank
        debug('exit via ctrl+D');
        tab.REPL.pexec('exit', {
          tab
        });
      }
    } else if (char === _Keys.KeyCodes.PAGEUP) {
      if ((0, _Capabilities.inBrowser)()) {
        debug('pageup');
        const {
          height
        } = document.body.getBoundingClientRect();
        document.querySelector('.kui--tab-content.visible .repl-inner').scrollBy(0, -height);
      }
    } else if (char === _Keys.KeyCodes.PAGEDOWN) {
      if ((0, _Capabilities.inBrowser)()) {
        debug('pagedown');
        const {
          height
        } = document.body.getBoundingClientRect();
        document.querySelector('.kui--tab-content.visible .repl-inner').scrollBy(0, +height);
      }
    } else if (char === _Keys.KeyCodes.L && (event.ctrlKey || (0, _Capabilities.inElectron)() && event.metaKey) || process.platform === 'darwin' && char === _Keys.KeyCodes.K && event.metaKey) {
      // clear screen; capture and restore the current
      // prompt value, in keeping with unix terminal
      // behavior
      _Events.eventChannelUnsafe.emit('/terminal/clear');
      _Events.eventChannelUnsafe.emit(`/terminal/clear/${this.props.uuid}`);
      _Events.eventChannelUnsafe.emit(`/close/views/${this.props.uuid}`);
      // restore the prompt cursor position
      // debug('restoring cursor position', currentCursorPosition)
      // getCurrentPrompt().setSelectionRange(currentCursorPosition, currentCursorPosition)
    } else if (char === _Keys.KeyCodes.DOWN || char === _Keys.KeyCodes.N && event.ctrlKey) {
      // going DOWN past the last history item will result in '', i.e. a blank line
      setTimeout(() => __awaiter(this, void 0, void 0, function* () {
        const historyModel = yield (yield Promise.resolve().then(() => require('@kui-shell/core/mdist/api/History'))).History(tab);
        const entry = historyModel.next();
        updateInputAndMoveCaretToEOL(this, entry);
      }));
    } else if (event.key === 'w' && event.ctrlKey) {
      const {
        prompt
      } = this.state;
      const idx = prompt.value.lastIndexOf(' ', prompt.value.charAt(prompt.value.length - 1) === ' ' ? prompt.value.length - 2 : prompt.value.length - 1);
      this.state.prompt.value = this.state.prompt.value.slice(0, idx + 1);
    }
  }
}