"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = onPaste;
exports.doPaste = void 0;
exports.onPasteAsync = onPasteAsync;
var _ClipboardTransfer = require("../ClipboardTransfer");
var _multilineInput = require("../../util/multiline-input");
/*
 * 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());
  });
};
/** We would like to use negative lookbehind, but Safari still does not support this. Thanks Apple */
function split(text) {
  if (text.length === 0) {
    return [];
  } else {
    const lines = [''];
    let escaped = false;
    for (let idx = 0; idx < text.length; idx++) {
      const c = text[idx];
      const isEscaped = escaped;
      escaped = false;
      if (!isEscaped) {
        if (c === '\\') {
          escaped = true;
        } else if (c === '\n') {
          lines.push('');
          continue;
        }
      }
      lines[lines.length - 1] += c;
    }
    return lines;
  }
}
const doPaste = (input, text, tab, prompt) => {
  // const prompt = event.currentTarget
  const lines = split(text);
  const pasteLooper = idx => __awaiter(void 0, void 0, void 0, function* () {
    if (idx === lines.length) {
      // all done...
      return Promise.resolve();
      /* } else if (lines[idx] === '') {
      // then this is a blank line, so skip it
      return pasteLooper(idx + 1) */
    } else if (lines[idx].length === 0) {
      // skip
    } else if (idx <= lines.length - 2) {
      // then this is a command line with a trailing newline
      yield tab.REPL.pexec(prompt.value + lines[idx], {
        tab
      });
      pasteLooper(idx + 1);
    } else {
      // then this is the last line, but without a trailing newline.
      // here, we add this command line to the current prompt, without executing it
      // paste the line with respect to the current prompt's
      // selection range; if there is no selection range, then
      // prompt.selectionStart will be the current caret position
      // (which is precisely what we want, i.e. to paste the given
      // text at the current caret position); if there is a
      // selectionEnd, then we will *also* replace the selection
      // range
      // and, then, when we are done, will position the caret just
      // after the pasted text:
      const newCaretPosition = prompt.selectionStart + lines[idx].length;
      const newValue = prompt.value.substring(0, prompt.selectionStart) + lines[idx] + prompt.value.substring(prompt.selectionEnd);
      // note how this will either place the new text at the caret
      // position, or replace the selected text (if selectionEnd !==
      // selectionStart)
      if (/\n/.test(lines[idx]) && !input.state.multiline) {
        // multi-line
        input.setState({
          multiline: true,
          pasteMultiLineTexts: newValue
        });
      } else {
        prompt.value = newValue;
        // restore the caret position
        prompt.setSelectionRange(newCaretPosition, newCaretPosition);
      }
      return Promise.resolve();
    }
  });
  return pasteLooper(0);
};
/**
 * User has requested that we paste something from the
 * clipboard.
 *
 * @return a Promise of when we will be done.
 *
 */
exports.doPaste = doPaste;
function onPasteAsync(event, tab, prompt) {
  const text = event.clipboardData.getData('text');
  if (text) {
    // we'll handle it from here!
    event.preventDefault();
    if ((0, _ClipboardTransfer.isClipboardTransferString)(text)) {
      // it'll be handled in ScrollableTerminal
      return;
    }
    if ((0, _multilineInput.isMultiLineHereDoc)(text)) {
      this.setState({
        multiline: true,
        pasteMultiLineTexts: text
      });
    } else {
      return doPaste(this, text, tab, prompt);
    }
  }
}
/**
 * User has requested that we paste something from the clipboard
 *
 */
function onPaste(event, tab, prompt) {
  onPasteAsync.bind(this)(event, tab, prompt);
}