// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

/* A repl library that you can include in your own code to get a runtime
 * interface to your program.
 *
 *   var repl = require("repl");
 *   // start repl on stdin
 *   repl.start("prompt> ");
 *
 *   // listen for unix socket connections and start repl on them
 *   net.createServer(function(socket) {
 *     repl.start("node via Unix socket> ", socket);
 *   }).listen("/tmp/node-repl-sock");
 *
 *   // listen for TCP socket connections and start repl on them
 *   net.createServer(function(socket) {
 *     repl.start("node via TCP socket> ", socket);
 *   }).listen(5001);
 *
 *   // expose foo to repl context
 *   repl.start("node > ").context.foo = "stdin is fun";
 */

'use strict';

const {
  builtinLibs,
  makeRequireFunction,
  addBuiltinLibsToObject
} = require('internal/modules/cjs/helpers');
const {
  isIdentifierStart,
  isIdentifierChar
} = require('internal/deps/acorn/dist/acorn');
const internalUtil = require('internal/util');
const util = require('util');
const { inherits } = util;
const Stream = require('stream');
const vm = require('vm');
const path = require('path');
const fs = require('fs');
const { Interface } = require('readline');
const { Console } = require('console');
const CJSModule = require('internal/modules/cjs/loader');
const domain = require('domain');
const debug = util.debuglog('repl');
const {
  ERR_CANNOT_WATCH_SIGINT,
  ERR_INVALID_ARG_TYPE,
  ERR_INVALID_REPL_EVAL_CONFIG,
  ERR_SCRIPT_EXECUTION_INTERRUPTED
} = require('internal/errors').codes;
const { sendInspectorCommand } = require('internal/util/inspector');
const { experimentalREPLAwait } = process.binding('config');
const { isRecoverableError } = require('internal/repl/recoverable');
const {
  getOwnNonIndexProperties,
  propertyFilter: {
    ALL_PROPERTIES,
    SKIP_SYMBOLS
  },
  startSigintWatchdog,
  stopSigintWatchdog
} = internalBinding('util');

// Lazy-loaded.
let processTopLevelAwait;

const parentModule = module;
const replMap = new WeakMap();

const GLOBAL_OBJECT_PROPERTIES = [
  'NaN', 'Infinity', 'undefined', 'eval', 'parseInt', 'parseFloat', 'isNaN',
  'isFinite', 'decodeURI', 'decodeURIComponent', 'encodeURI',
  'encodeURIComponent', 'Object', 'Function', 'Array', 'String', 'Boolean',
  'Number', 'Date', 'RegExp', 'Error', 'EvalError', 'RangeError',
  'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Math', 'JSON'
];
const GLOBAL_OBJECT_PROPERTY_MAP = {};
for (var n = 0; n < GLOBAL_OBJECT_PROPERTIES.length; n++) {
  GLOBAL_OBJECT_PROPERTY_MAP[GLOBAL_OBJECT_PROPERTIES[n]] =
    GLOBAL_OBJECT_PROPERTIES[n];
}
const kBufferedCommandSymbol = Symbol('bufferedCommand');
const kContextId = Symbol('contextId');

try {
  // Hack for require.resolve("./relative") to work properly.
  module.filename = path.resolve('repl');
} catch (e) {
  // path.resolve('repl') fails when the current working directory has been
  // deleted.  Fall back to the directory name of the (absolute) executable
  // path.  It's not really correct but what are the alternatives?
  const dirname = path.dirname(process.execPath);
  module.filename = path.resolve(dirname, 'repl');
}

// Hack for repl require to work properly with node_modules folders
module.paths = CJSModule._nodeModulePaths(module.filename);

// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

// Can overridden with custom print functions, such as `probe` or `eyes.js`.
// This is the default "writer" value if none is passed in the REPL options.
const writer = exports.writer = (obj) => util.inspect(obj, writer.options);
writer.options = Object.assign({},
                               util.inspect.defaultOptions,
                               { showProxy: true, depth: 2 });

exports._builtinLibs = builtinLibs;

function REPLServer(prompt,
                    stream,
                    eval_,
                    useGlobal,
                    ignoreUndefined,
                    replMode) {
  if (!(this instanceof REPLServer)) {
    return new REPLServer(prompt,
                          stream,
                          eval_,
                          useGlobal,
                          ignoreUndefined,
                          replMode);
  }

  var options, input, output, dom, breakEvalOnSigint;
  if (prompt !== null && typeof prompt === 'object') {
    // an options object was given
    options = prompt;
    stream = options.stream || options.socket;
    input = options.input;
    output = options.output;
    eval_ = options.eval;
    useGlobal = options.useGlobal;
    ignoreUndefined = options.ignoreUndefined;
    prompt = options.prompt;
    dom = options.domain;
    replMode = options.replMode;
    breakEvalOnSigint = options.breakEvalOnSigint;
  } else {
    options = {};
  }

  if (breakEvalOnSigint && eval_) {
    // Allowing this would not reflect user expectations.
    // breakEvalOnSigint affects only the behavior of the default eval().
    throw new ERR_INVALID_REPL_EVAL_CONFIG();
  }

  var self = this;

  self._domain = dom || domain.create();
  self.useGlobal = !!useGlobal;
  self.ignoreUndefined = !!ignoreUndefined;
  self.replMode = replMode || exports.REPL_MODE_SLOPPY;
  self.underscoreAssigned = false;
  self.last = undefined;
  self.underscoreErrAssigned = false;
  self.lastError = undefined;
  self.breakEvalOnSigint = !!breakEvalOnSigint;
  self.editorMode = false;
  // Context id for use with the inspector protocol.
  self[kContextId] = undefined;

  // Just for backwards compat, see github.com/joyent/node/pull/7127
  self.rli = this;

  const savedRegExMatches = ['', '', '', '', '', '', '', '', '', ''];
  const sep = '\u0000\u0000\u0000';
  const regExMatcher = new RegExp(`^${sep}(.*)${sep}(.*)${sep}(.*)${sep}(.*)` +
                                  `${sep}(.*)${sep}(.*)${sep}(.*)${sep}(.*)` +
                                  `${sep}(.*)$`);

  eval_ = eval_ || defaultEval;

  // Pause taking in new input, and store the keys in a buffer.
  const pausedBuffer = [];
  let paused = false;
  function pause() {
    paused = true;
  }
  function unpause() {
    if (!paused) return;
    paused = false;
    let entry;
    while (entry = pausedBuffer.shift()) {
      const [type, payload] = entry;
      switch (type) {
        case 'key': {
          const [d, key] = payload;
          self._ttyWrite(d, key);
          break;
        }
        case 'close':
          self.emit('exit');
          break;
      }
      if (paused) {
        break;
      }
    }
  }

  function defaultEval(code, context, file, cb) {
    var err, result, script, wrappedErr;
    var wrappedCmd = false;
    var awaitPromise = false;
    var input = code;

    if (/^\s*\{/.test(code) && /\}\s*$/.test(code)) {
      // It's confusing for `{ a : 1 }` to be interpreted as a block
      // statement rather than an object literal.  So, we first try
      // to wrap it in parentheses, so that it will be interpreted as
      // an expression.  Note that if the above condition changes,
      // lib/internal/repl/recoverable.js needs to be changed to match.
      code = `(${code.trim()})\n`;
      wrappedCmd = true;
    }

    if (experimentalREPLAwait && code.includes('await')) {
      if (processTopLevelAwait === undefined) {
        ({ processTopLevelAwait } = require('internal/repl/await'));
      }

      const potentialWrappedCode = processTopLevelAwait(code);
      if (potentialWrappedCode !== null) {
        code = potentialWrappedCode;
        wrappedCmd = true;
        awaitPromise = true;
      }
    }

    // First, create the Script object to check the syntax
    if (code === '\n')
      return cb(null);

    while (true) {
      try {
        if (!/^\s*$/.test(code) &&
            self.replMode === exports.REPL_MODE_STRICT) {
          // "void 0" keeps the repl from returning "use strict" as the result
          // value for statements and declarations that don't return a value.
          code = `'use strict'; void 0;\n${code}`;
        }
        script = vm.createScript(code, {
          filename: file,
          displayErrors: true
        });
      } catch (e) {
        debug('parse error %j', code, e);
        if (wrappedCmd) {
          // Unwrap and try again
          wrappedCmd = false;
          awaitPromise = false;
          code = input;
          wrappedErr = e;
          continue;
        }
        // Preserve original error for wrapped command
        const error = wrappedErr || e;
        if (isRecoverableError(error, code))
          err = new Recoverable(error);
        else
          err = error;
      }
      break;
    }

    // This will set the values from `savedRegExMatches` to corresponding
    // predefined RegExp properties `RegExp.$1`, `RegExp.$2` ... `RegExp.$9`
    regExMatcher.test(savedRegExMatches.join(sep));

    let finished = false;
    function finishExecution(err, result) {
      if (finished) return;
      finished = true;

      // After executing the current expression, store the values of RegExp
      // predefined properties back in `savedRegExMatches`
      for (var idx = 1; idx < savedRegExMatches.length; idx += 1) {
        savedRegExMatches[idx] = RegExp[`$${idx}`];
      }

      cb(err, result);
    }

    if (!err) {
      // Unset raw mode during evaluation so that Ctrl+C raises a signal.
      let previouslyInRawMode;
      if (self.breakEvalOnSigint) {
        // Start the SIGINT watchdog before entering raw mode so that a very
        // quick Ctrl+C doesn't lead to aborting the process completely.
        if (!startSigintWatchdog())
          throw new ERR_CANNOT_WATCH_SIGINT();
        previouslyInRawMode = self._setRawMode(false);
      }

      try {
        try {
          const scriptOptions = {
            displayErrors: false,
            breakOnSigint: self.breakEvalOnSigint
          };

          if (self.useGlobal) {
            result = script.runInThisContext(scriptOptions);
          } else {
            result = script.runInContext(context, scriptOptions);
          }
        } finally {
          if (self.breakEvalOnSigint) {
            // Reset terminal mode to its previous value.
            self._setRawMode(previouslyInRawMode);

            // Returns true if there were pending SIGINTs *after* the script
            // has terminated without being interrupted itself.
            if (stopSigintWatchdog()) {
              self.emit('SIGINT');
            }
          }
        }
      } catch (e) {
        err = e;

        if (process.domain) {
          debug('not recoverable, send to domain');
          process.domain.emit('error', err);
          process.domain.exit();
          return;
        }
      }

      if (awaitPromise && !err) {
        let sigintListener;
        pause();
        let promise = result;
        if (self.breakEvalOnSigint) {
          const interrupt = new Promise((resolve, reject) => {
            sigintListener = () => {
              const tmp = Error.stackTraceLimit;
              Error.stackTraceLimit = 0;
              const err = new ERR_SCRIPT_EXECUTION_INTERRUPTED();
              Error.stackTraceLimit = tmp;
              reject(err);
            };
            prioritizedSigintQueue.add(sigintListener);
          });
          promise = Promise.race([promise, interrupt]);
        }

        promise.then((result) => {
          // Remove prioritized SIGINT listener if it was not called.
          // TODO(TimothyGu): Use Promise.prototype.finally when it becomes
          // available.
          prioritizedSigintQueue.delete(sigintListener);

          finishExecution(undefined, result);
          unpause();
        }, (err) => {
          // Remove prioritized SIGINT listener if it was not called.
          prioritizedSigintQueue.delete(sigintListener);

          unpause();
          if (err && process.domain) {
            debug('not recoverable, send to domain');
            process.domain.emit('error', err);
            process.domain.exit();
            return;
          }
          finishExecution(err);
        });
      }
    }

    if (!awaitPromise || err) {
      finishExecution(err, result);
    }
  }

  self.eval = self._domain.bind(eval_);

  self._domain.on('error', function debugDomainError(e) {
    debug('domain error');
    let errStack = '';

    if (typeof e === 'object' && e !== null) {
      const pstrace = Error.prepareStackTrace;
      Error.prepareStackTrace = prepareStackTrace(pstrace);
      internalUtil.decorateErrorStack(e);
      Error.prepareStackTrace = pstrace;

      if (e.domainThrown) {
        delete e.domain;
        delete e.domainThrown;
      }

      if (internalUtil.isError(e)) {
        if (e.stack) {
          if (e.name === 'SyntaxError') {
            // Remove stack trace.
            e.stack = e.stack
              .replace(/^repl:\d+\r?\n/, '')
              .replace(/^\s+at\s.*\n?/gm, '');
          } else if (self.replMode === exports.REPL_MODE_STRICT) {
            e.stack = e.stack.replace(/(\s+at\s+repl:)(\d+)/,
                                      (_, pre, line) => pre + (line - 1));
          }
        }
        errStack = util.inspect(e);

        // Remove one line error braces to keep the old style in place.
        if (errStack[errStack.length - 1] === ']') {
          errStack = errStack.slice(1, -1);
        }
      }
    }

    if (errStack === '') {
      errStack = `Thrown: ${util.inspect(e)}`;
    }

    if (!self.underscoreErrAssigned) {
      self.lastError = e;
    }

    const top = replMap.get(self);
    top.outputStream.write(`${errStack}\n`);
    top.clearBufferedCommand();
    top.lines.level = [];
    top.displayPrompt();
  });

  if (!input && !output) {
    // legacy API, passing a 'stream'/'socket' option
    if (!stream) {
      // Use stdin and stdout as the default streams if none were given
      stream = process;
    }
    // We're given a duplex readable/writable Stream, like a `net.Socket`
    // or a custom object with 2 streams, or the `process` object
    input = stream.stdin || stream;
    output = stream.stdout || stream;
  }

  self.inputStream = input;
  self.outputStream = output;

  self.resetContext();
  self.lines.level = [];

  self.clearBufferedCommand();
  Object.defineProperty(this, 'bufferedCommand', {
    get: util.deprecate(() => self[kBufferedCommandSymbol],
                        'REPLServer.bufferedCommand is deprecated', 'DEP0074'),
    set: util.deprecate((val) => self[kBufferedCommandSymbol] = val,
                        'REPLServer.bufferedCommand is deprecated', 'DEP0074'),
    enumerable: true
  });

  // Figure out which "complete" function to use.
  self.completer = (typeof options.completer === 'function') ?
    options.completer : completer;

  function completer(text, cb) {
    complete.call(self, text, self.editorMode ?
      self.completeOnEditorMode(cb) : cb);
  }

  Interface.call(this, {
    input: self.inputStream,
    output: self.outputStream,
    completer: self.completer,
    terminal: options.terminal,
    historySize: options.historySize,
    prompt
  });

  this.commands = Object.create(null);
  defineDefaultCommands(this);

  // Figure out which "writer" function to use
  self.writer = options.writer || exports.writer;

  if (options.useColors === undefined) {
    options.useColors = self.terminal;
  }
  self.useColors = !!options.useColors;

  if (self.useColors && self.writer === writer) {
    // Turn on ANSI coloring.
    self.writer = (obj) => util.inspect(obj, self.writer.options);
    self.writer.options = Object.assign({}, writer.options, { colors: true });
  }

  function filterInternalStackFrames(structuredStack) {
    // Search from the bottom of the call stack to
    // find the first frame with a null function name
    if (typeof structuredStack !== 'object')
      return structuredStack;
    const idx = structuredStack.reverse().findIndex(
      (frame) => frame.getFunctionName() === null);

    // If found, get rid of it and everything below it
    structuredStack = structuredStack.splice(idx + 1);
    return structuredStack;
  }

  function prepareStackTrace(fn) {
    return (error, stackFrames) => {
      const frames = filterInternalStackFrames(stackFrames);
      if (fn) {
        return fn(error, frames);
      }
      frames.push(error);
      return frames.reverse().join('\n    at ');
    };
  }

  function _parseREPLKeyword(keyword, rest) {
    var cmd = this.commands[keyword];
    if (cmd) {
      cmd.action.call(this, rest);
      return true;
    }
    return false;
  }

  self.parseREPLKeyword = util.deprecate(
    _parseREPLKeyword,
    'REPLServer.parseREPLKeyword() is deprecated',
    'DEP0075');

  self.on('close', function emitExit() {
    if (paused) {
      pausedBuffer.push(['close']);
      return;
    }
    self.emit('exit');
  });

  var sawSIGINT = false;
  var sawCtrlD = false;
  const prioritizedSigintQueue = new Set();
  self.on('SIGINT', function onSigInt() {
    if (prioritizedSigintQueue.size > 0) {
      for (const task of prioritizedSigintQueue) {
        task();
      }
      return;
    }

    var empty = self.line.length === 0;
    self.clearLine();
    _turnOffEditorMode(self);

    const cmd = self[kBufferedCommandSymbol];
    if (!(cmd && cmd.length > 0) && empty) {
      if (sawSIGINT) {
        self.close();
        sawSIGINT = false;
        return;
      }
      self.output.write('(To exit, press ^C again or type .exit)\n');
      sawSIGINT = true;
    } else {
      sawSIGINT = false;
    }

    self.clearBufferedCommand();
    self.lines.level = [];
    self.displayPrompt();
  });

  self.on('line', function onLine(cmd) {
    debug('line %j', cmd);
    cmd = cmd || '';
    sawSIGINT = false;

    if (self.editorMode) {
      self[kBufferedCommandSymbol] += cmd + '\n';

      // code alignment
      const matches = self._sawKeyPress ? cmd.match(/^\s+/) : null;
      if (matches) {
        const prefix = matches[0];
        self.write(prefix);
        self.line = prefix;
        self.cursor = prefix.length;
      }
      _memory.call(self, cmd);
      return;
    }

    // Check REPL keywords and empty lines against a trimmed line input.
    const trimmedCmd = cmd.trim();

    // Check to see if a REPL keyword was used. If it returns true,
    // display next prompt and return.
    if (trimmedCmd) {
      if (trimmedCmd.charAt(0) === '.' && trimmedCmd.charAt(1) !== '.' &&
          Number.isNaN(parseFloat(trimmedCmd))) {
        const matches = trimmedCmd.match(/^\.([^\s]+)\s*(.*)$/);
        const keyword = matches && matches[1];
        const rest = matches && matches[2];
        if (_parseREPLKeyword.call(self, keyword, rest) === true) {
          return;
        }
        if (!self[kBufferedCommandSymbol]) {
          self.outputStream.write('Invalid REPL keyword\n');
          finish(null);
          return;
        }
      }
    }

    const evalCmd = self[kBufferedCommandSymbol] + cmd + '\n';

    debug('eval %j', evalCmd);
    self.eval(evalCmd, self.context, 'repl', finish);

    function finish(e, ret) {
      debug('finish', e, ret);
      _memory.call(self, cmd);

      if (e && !self[kBufferedCommandSymbol] && cmd.trim().startsWith('npm ')) {
        self.outputStream.write('npm should be run outside of the ' +
                                'node repl, in your normal shell.\n' +
                                '(Press Control-D to exit.)\n');
        self.clearBufferedCommand();
        self.displayPrompt();
        return;
      }

      // If error was SyntaxError and not JSON.parse error
      if (e) {
        if (e instanceof Recoverable && !sawCtrlD) {
          // Start buffering data like that:
          // {
          // ...  x: 1
          // ... }
          self[kBufferedCommandSymbol] += cmd + '\n';
          self.displayPrompt();
          return;
        } else {
          self._domain.emit('error', e.err || e);
        }
      }

      // Clear buffer if no SyntaxErrors
      self.clearBufferedCommand();
      sawCtrlD = false;

      // If we got any output - print it (if no error)
      if (!e &&
          // When an invalid REPL command is used, error message is printed
          // immediately. We don't have to print anything else. So, only when
          // the second argument to this function is there, print it.
          arguments.length === 2 &&
          (!self.ignoreUndefined || ret !== undefined)) {
        if (!self.underscoreAssigned) {
          self.last = ret;
        }
        self.outputStream.write(self.writer(ret) + '\n');
      }

      // Display prompt again
      self.displayPrompt();
    }
  });

  self.on('SIGCONT', function onSigCont() {
    if (self.editorMode) {
      self.outputStream.write(`${self._initialPrompt}.editor\n`);
      self.outputStream.write(
        '// Entering editor mode (^D to finish, ^C to cancel)\n');
      self.outputStream.write(`${self[kBufferedCommandSymbol]}\n`);
      self.prompt(true);
    } else {
      self.displayPrompt(true);
    }
  });

  // Wrap readline tty to enable editor mode and pausing.
  const ttyWrite = self._ttyWrite.bind(self);
  self._ttyWrite = (d, key) => {
    key = key || {};
    if (paused && !(self.breakEvalOnSigint && key.ctrl && key.name === 'c')) {
      pausedBuffer.push(['key', [d, key]]);
      return;
    }
    if (!self.editorMode || !self.terminal) {
      ttyWrite(d, key);
      return;
    }

    // Editor mode
    if (key.ctrl && !key.shift) {
      switch (key.name) {
        case 'd': // End editor mode
          _turnOffEditorMode(self);
          sawCtrlD = true;
          ttyWrite(d, { name: 'return' });
          break;
        case 'n': // Override next history item
        case 'p': // Override previous history item
          break;
        default:
          ttyWrite(d, key);
      }
    } else {
      switch (key.name) {
        case 'up':   // Override previous history item
        case 'down': // Override next history item
          break;
        case 'tab':
          // Prevent double tab behavior
          self._previousKey = null;
          ttyWrite(d, key);
          break;
        default:
          ttyWrite(d, key);
      }
    }
  };

  self.displayPrompt();
}
inherits(REPLServer, Interface);
exports.REPLServer = REPLServer;

exports.REPL_MODE_SLOPPY = Symbol('repl-sloppy');
exports.REPL_MODE_STRICT = Symbol('repl-strict');

// prompt is a string to print on each line for the prompt,
// source is a stream to use for I/O, defaulting to stdin/stdout.
exports.start = function(prompt,
                         source,
                         eval_,
                         useGlobal,
                         ignoreUndefined,
                         replMode) {
  var repl = new REPLServer(prompt,
                            source,
                            eval_,
                            useGlobal,
                            ignoreUndefined,
                            replMode);
  if (!exports.repl) exports.repl = repl;
  replMap.set(repl, repl);
  return repl;
};

REPLServer.prototype.clearBufferedCommand = function clearBufferedCommand() {
  this[kBufferedCommandSymbol] = '';
};

REPLServer.prototype.close = function close() {
  if (this.terminal && this._flushing && !this._closingOnFlush) {
    this._closingOnFlush = true;
    this.once('flushHistory', () =>
      Interface.prototype.close.call(this)
    );

    return;
  }
  process.nextTick(() =>
    Interface.prototype.close.call(this)
  );
};

REPLServer.prototype.createContext = function() {
  var context;
  if (this.useGlobal) {
    context = global;
  } else {
    sendInspectorCommand((session) => {
      session.post('Runtime.enable');
      session.once('Runtime.executionContextCreated', ({ params }) => {
        this[kContextId] = params.context.id;
      });
      context = vm.createContext();
      session.post('Runtime.disable');
    }, () => {
      context = vm.createContext();
    });
    context.global = context;
    const _console = new Console(this.outputStream);
    Object.defineProperty(context, 'console', {
      configurable: true,
      writable: true,
      value: _console
    });

    var names = Object.getOwnPropertyNames(global);
    for (var n = 0; n < names.length; n++) {
      var name = names[n];
      if (name === 'console' || name === 'global')
        continue;
      if (GLOBAL_OBJECT_PROPERTY_MAP[name] === undefined) {
        Object.defineProperty(context, name,
                              Object.getOwnPropertyDescriptor(global, name));
      }
    }
  }

  var module = new CJSModule('<repl>');
  module.paths =
    CJSModule._resolveLookupPaths('<repl>', parentModule, true) || [];

  Object.defineProperty(context, 'module', {
    configurable: true,
    writable: true,
    value: module
  });
  Object.defineProperty(context, 'require', {
    configurable: true,
    writable: true,
    value: makeRequireFunction(module)
  });

  addBuiltinLibsToObject(context);

  return context;
};

REPLServer.prototype.resetContext = function() {
  this.context = this.createContext();
  this.underscoreAssigned = false;
  this.underscoreErrAssigned = false;
  this.lines = [];
  this.lines.level = [];

  Object.defineProperty(this.context, '_', {
    configurable: true,
    get: () => this.last,
    set: (value) => {
      this.last = value;
      if (!this.underscoreAssigned) {
        this.underscoreAssigned = true;
        this.outputStream.write('Expression assignment to _ now disabled.\n');
      }
    }
  });

  Object.defineProperty(this.context, '_error', {
    configurable: true,
    get: () => this.lastError,
    set: (value) => {
      this.lastError = value;
      if (!this.underscoreErrAssigned) {
        this.underscoreErrAssigned = true;
        this.outputStream.write(
          'Expression assignment to _error now disabled.\n');
      }
    }
  });

  // Allow REPL extensions to extend the new context
  this.emit('reset', this.context);
};

REPLServer.prototype.displayPrompt = function(preserveCursor) {
  var prompt = this._initialPrompt;
  if (this[kBufferedCommandSymbol].length) {
    prompt = '...';
    const len = this.lines.level.length ? this.lines.level.length - 1 : 0;
    const levelInd = '..'.repeat(len);
    prompt += levelInd + ' ';
  }

  // Do not overwrite `_initialPrompt` here
  REPLServer.super_.prototype.setPrompt.call(this, prompt);
  this.prompt(preserveCursor);
};

// When invoked as an API method, overwrite _initialPrompt
REPLServer.prototype.setPrompt = function setPrompt(prompt) {
  this._initialPrompt = prompt;
  REPLServer.super_.prototype.setPrompt.call(this, prompt);
};

REPLServer.prototype.turnOffEditorMode = util.deprecate(
  function() { _turnOffEditorMode(this); },
  'REPLServer.turnOffEditorMode() is deprecated',
  'DEP0078');

// A stream to push an array into a REPL
// used in REPLServer.complete
function ArrayStream() {
  Stream.call(this);

  this.run = function(data) {
    for (var n = 0; n < data.length; n++)
      this.emit('data', `${data[n]}\n`);
  };
}
util.inherits(ArrayStream, Stream);
ArrayStream.prototype.readable = true;
ArrayStream.prototype.writable = true;
ArrayStream.prototype.resume = function() {};
ArrayStream.prototype.write = function() {};

const requireRE = /\brequire\s*\(['"](([\w@./-]+\/)?(?:[\w@./-]*))/;
const simpleExpressionRE =
    /(?:[a-zA-Z_$](?:\w|\$)*\.)*[a-zA-Z_$](?:\w|\$)*\.?$/;

function isIdentifier(str) {
  if (str === '') {
    return false;
  }
  const first = str.codePointAt(0);
  if (!isIdentifierStart(first)) {
    return false;
  }
  const firstLen = first > 0xffff ? 2 : 1;
  for (var i = firstLen; i < str.length; i += 1) {
    const cp = str.codePointAt(i);
    if (!isIdentifierChar(cp)) {
      return false;
    }
    if (cp > 0xffff) {
      i += 1;
    }
  }
  return true;
}

function filteredOwnPropertyNames(obj) {
  if (!obj) return [];
  const filter = ALL_PROPERTIES | SKIP_SYMBOLS;
  return getOwnNonIndexProperties(obj, filter).filter(isIdentifier);
}

function getGlobalLexicalScopeNames(contextId) {
  return sendInspectorCommand((session) => {
    let names = [];
    session.post('Runtime.globalLexicalScopeNames', {
      executionContextId: contextId
    }, (error, result) => {
      if (!error) names = result.names;
    });
    return names;
  }, () => []);
}

REPLServer.prototype.complete = function() {
  this.completer.apply(this, arguments);
};

// Provide a list of completions for the given leading text. This is
// given to the readline interface for handling tab completion.
//
// Example:
//  complete('var foo = util.')
//    -> [['util.print', 'util.debug', 'util.log', 'util.inspect'],
//        'util.' ]
//
// Warning: This eval's code like "foo.bar.baz", so it will run property
// getter code.
function complete(line, callback) {
  // There may be local variables to evaluate, try a nested REPL
  if (this[kBufferedCommandSymbol] !== undefined &&
      this[kBufferedCommandSymbol].length) {
    // Get a new array of inputted lines
    var tmp = this.lines.slice();
    // Kill off all function declarations to push all local variables into
    // global scope
    for (var n = 0; n < this.lines.level.length; n++) {
      var kill = this.lines.level[n];
      if (kill.isFunction)
        tmp[kill.line] = '';
    }
    var flat = new ArrayStream();         // make a new "input" stream
    var magic = new REPLServer('', flat); // make a nested REPL
    replMap.set(magic, replMap.get(this));
    flat.run(tmp);                        // eval the flattened code
    // all this is only profitable if the nested REPL
    // does not have a bufferedCommand
    if (!magic[kBufferedCommandSymbol]) {
      magic._domain.on('error', (err) => { throw err; });
      return magic.complete(line, callback);
    }
  }

  var completions;
  // List of completion lists, one for each inheritance "level"
  var completionGroups = [];
  var completeOn, i, group, c;

  // REPL commands (e.g. ".break").
  var filter;
  var match = null;
  match = line.match(/^\s*\.(\w*)$/);
  if (match) {
    completionGroups.push(Object.keys(this.commands));
    completeOn = match[1];
    if (match[1].length) {
      filter = match[1];
    }

    completionGroupsLoaded();
  } else if (match = line.match(requireRE)) {
    // require('...<Tab>')
    const exts = Object.keys(this.context.require.extensions);
    var indexRe = new RegExp('^index(?:' + exts.map(regexpEscape).join('|') +
                             ')$');
    var versionedFileNamesRe = /-\d+\.\d+/;

    completeOn = match[1];
    var subdir = match[2] || '';
    filter = match[1];
    var dir, files, f, name, base, ext, abs, subfiles, s, isDirectory;
    group = [];
    let paths = [];

    if (completeOn === '.') {
      group = ['./', '../'];
    } else if (completeOn === '..') {
      group = ['../'];
    } else if (/^\.\.?\//.test(completeOn)) {
      paths = [process.cwd()];
    } else {
      paths = module.paths.concat(CJSModule.globalPaths);
    }

    for (i = 0; i < paths.length; i++) {
      dir = path.resolve(paths[i], subdir);
      try {
        files = fs.readdirSync(dir);
      } catch (e) {
        continue;
      }
      for (f = 0; f < files.length; f++) {
        name = files[f];
        ext = path.extname(name);
        base = name.slice(0, -ext.length);
        if (versionedFileNamesRe.test(base) || name === '.npm') {
          // Exclude versioned names that 'npm' installs.
          continue;
        }
        abs = path.resolve(dir, name);
        try {
          isDirectory = fs.statSync(abs).isDirectory();
        } catch (e) {
          continue;
        }
        if (isDirectory) {
          group.push(subdir + name + '/');
          try {
            subfiles = fs.readdirSync(abs);
          } catch (e) {
            continue;
          }
          for (s = 0; s < subfiles.length; s++) {
            if (indexRe.test(subfiles[s])) {
              group.push(subdir + name);
            }
          }
        } else if (exts.includes(ext) && (!subdir || base !== 'index')) {
          group.push(subdir + base);
        }
      }
    }
    if (group.length) {
      completionGroups.push(group);
    }

    if (!subdir) {
      completionGroups.push(exports._builtinLibs);
    }

    completionGroupsLoaded();

  // Handle variable member lookup.
  // We support simple chained expressions like the following (no function
  // calls, etc.). That is for simplicity and also because we *eval* that
  // leading expression so for safety (see WARNING above) don't want to
  // eval function calls.
  //
  //   foo.bar<|>     # completions for 'foo' with filter 'bar'
  //   spam.eggs.<|>  # completions for 'spam.eggs' with filter ''
  //   foo<|>         # all scope vars with filter 'foo'
  //   foo.<|>        # completions for 'foo' with filter ''
  } else if (line.length === 0 || /\w|\.|\$/.test(line[line.length - 1])) {
    match = simpleExpressionRE.exec(line);
    if (line.length === 0 || match) {
      var expr;
      completeOn = (match ? match[0] : '');
      if (line.length === 0) {
        filter = '';
        expr = '';
      } else if (line[line.length - 1] === '.') {
        filter = '';
        expr = match[0].slice(0, match[0].length - 1);
      } else {
        var bits = match[0].split('.');
        filter = bits.pop();
        expr = bits.join('.');
      }

      // Resolve expr and get its completions.
      var memberGroups = [];
      if (!expr) {
        // If context is instance of vm.ScriptContext
        // Get global vars synchronously
        if (this.useGlobal || vm.isContext(this.context)) {
          completionGroups.push(getGlobalLexicalScopeNames(this[kContextId]));
          var contextProto = this.context;
          while (contextProto = Object.getPrototypeOf(contextProto)) {
            completionGroups.push(
              filteredOwnPropertyNames.call(this, contextProto));
          }
          completionGroups.push(
            filteredOwnPropertyNames.call(this, this.context));
          addStandardGlobals(completionGroups, filter);
          completionGroupsLoaded();
        } else {
          this.eval('.scope', this.context, 'repl', function ev(err, globals) {
            if (err || !Array.isArray(globals)) {
              addStandardGlobals(completionGroups, filter);
            } else if (Array.isArray(globals[0])) {
              // Add grouped globals
              for (var n = 0; n < globals.length; n++)
                completionGroups.push(globals[n]);
            } else {
              completionGroups.push(globals);
              addStandardGlobals(completionGroups, filter);
            }
            completionGroupsLoaded();
          });
        }
      } else {
        const evalExpr = `try { ${expr} } catch (e) {}`;
        this.eval(evalExpr, this.context, 'repl', (e, obj) => {
          if (obj != null) {
            if (typeof obj === 'object' || typeof obj === 'function') {
              try {
                memberGroups.push(filteredOwnPropertyNames.call(this, obj));
              } catch (ex) {
                // Probably a Proxy object without `getOwnPropertyNames` trap.
                // We simply ignore it here, as we don't want to break the
                // autocompletion. Fixes the bug
                // https://github.com/nodejs/node/issues/2119
              }
            }
            // works for non-objects
            try {
              var sentinel = 5;
              var p;
              if (typeof obj === 'object' || typeof obj === 'function') {
                p = Object.getPrototypeOf(obj);
              } else {
                p = obj.constructor ? obj.constructor.prototype : null;
              }
              while (p !== null) {
                memberGroups.push(filteredOwnPropertyNames.call(this, p));
                p = Object.getPrototypeOf(p);
                // Circular refs possible? Let's guard against that.
                sentinel--;
                if (sentinel <= 0) {
                  break;
                }
              }
            } catch (e) {}
          }

          if (memberGroups.length) {
            for (i = 0; i < memberGroups.length; i++) {
              completionGroups.push(
                memberGroups[i].map((member) => `${expr}.${member}`));
            }
            if (filter) {
              filter = `${expr}.${filter}`;
            }
          }

          completionGroupsLoaded();
        });
      }
    } else {
      completionGroupsLoaded();
    }
  } else {
    completionGroupsLoaded();
  }

  // Will be called when all completionGroups are in place
  // Useful for async autocompletion
  function completionGroupsLoaded() {
    // Filter, sort (within each group), uniq and merge the completion groups.
    if (completionGroups.length && filter) {
      var newCompletionGroups = [];
      for (i = 0; i < completionGroups.length; i++) {
        group = completionGroups[i]
          .filter((elem) => elem.indexOf(filter) === 0);
        if (group.length) {
          newCompletionGroups.push(group);
        }
      }
      completionGroups = newCompletionGroups;
    }

    if (completionGroups.length) {
      var uniq = {};  // Unique completions across all groups
      completions = [];
      // Completion group 0 is the "closest"
      // (least far up the inheritance chain)
      // so we put its completions last: to be closest in the REPL.
      for (i = 0; i < completionGroups.length; i++) {
        group = completionGroups[i];
        group.sort();
        for (var j = group.length - 1; j >= 0; j--) {
          c = group[j];
          if (!hasOwnProperty(uniq, c)) {
            completions.unshift(c);
            uniq[c] = true;
          }
        }
        completions.unshift(''); // Separator btwn groups
      }
      while (completions.length && completions[0] === '') {
        completions.shift();
      }
    }

    callback(null, [completions || [], completeOn]);
  }
}

function longestCommonPrefix(arr = []) {
  const cnt = arr.length;
  if (cnt === 0) return '';
  if (cnt === 1) return arr[0];

  const first = arr[0];
  // complexity: O(m * n)
  for (var m = 0; m < first.length; m++) {
    const c = first[m];
    for (var n = 1; n < cnt; n++) {
      const entry = arr[n];
      if (m >= entry.length || c !== entry[m]) {
        return first.substring(0, m);
      }
    }
  }
  return first;
}

REPLServer.prototype.completeOnEditorMode = (callback) => (err, results) => {
  if (err) return callback(err);

  const [completions, completeOn = ''] = results;
  const prefixLength = completeOn.length;

  if (prefixLength === 0) return callback(null, [[], completeOn]);

  const isNotEmpty = (v) => v.length > 0;
  const trimCompleteOnPrefix = (v) => v.substring(prefixLength);
  const data = completions.filter(isNotEmpty).map(trimCompleteOnPrefix);

  callback(null, [[`${completeOn}${longestCommonPrefix(data)}`], completeOn]);
};

REPLServer.prototype.defineCommand = function(keyword, cmd) {
  if (typeof cmd === 'function') {
    cmd = { action: cmd };
  } else if (typeof cmd.action !== 'function') {
    throw new ERR_INVALID_ARG_TYPE('action', 'Function', cmd.action);
  }
  this.commands[keyword] = cmd;
};

REPLServer.prototype.memory = util.deprecate(
  _memory,
  'REPLServer.memory() is deprecated',
  'DEP0082');

function _memory(cmd) {
  const self = this;
  self.lines = self.lines || [];
  self.lines.level = self.lines.level || [];

  // Save the line so I can do magic later
  if (cmd) {
    // TODO should I tab the level?
    const len = self.lines.level.length ? self.lines.level.length - 1 : 0;
    self.lines.push('  '.repeat(len) + cmd);
  } else {
    // I don't want to not change the format too much...
    self.lines.push('');
  }

  // I need to know "depth."
  // Because I can not tell the difference between a } that
  // closes an object literal and a } that closes a function
  if (cmd) {
    // Going down is { and (   e.g. function() {
    // going up is } and )
    var dw = cmd.match(/{|\(/g);
    var up = cmd.match(/}|\)/g);
    up = up ? up.length : 0;
    dw = dw ? dw.length : 0;
    var depth = dw - up;

    if (depth) {
      (function workIt() {
        if (depth > 0) {
          // Going... down.
          // Push the line#, depth count, and if the line is a function.
          // Since JS only has functional scope I only need to remove
          // "function() {" lines, clearly this will not work for
          // "function()
          // {" but nothing should break, only tab completion for local
          // scope will not work for this function.
          self.lines.level.push({
            line: self.lines.length - 1,
            depth: depth,
            isFunction: /\bfunction\b/.test(cmd)
          });
        } else if (depth < 0) {
          // Going... up.
          var curr = self.lines.level.pop();
          if (curr) {
            var tmp = curr.depth + depth;
            if (tmp < 0) {
              // More to go, recurse
              depth += curr.depth;
              workIt();
            } else if (tmp > 0) {
              // Remove and push back
              curr.depth += depth;
              self.lines.level.push(curr);
            }
          }
        }
      }());
    }

    // it is possible to determine a syntax error at this point.
    // if the REPL still has a bufferedCommand and
    // self.lines.level.length === 0
    // TODO? keep a log of level so that any syntax breaking lines can
    // be cleared on .break and in the case of a syntax error?
    // TODO? if a log was kept, then I could clear the bufferedCommand and
    // eval these lines and throw the syntax error
  } else {
    self.lines.level = [];
  }
}

function addStandardGlobals(completionGroups, filter) {
  // Global object properties
  // (http://www.ecma-international.org/publications/standards/Ecma-262.htm)
  completionGroups.push(GLOBAL_OBJECT_PROPERTIES);
  // Common keywords. Exclude for completion on the empty string, b/c
  // they just get in the way.
  if (filter) {
    completionGroups.push([
      'async', 'await', 'break', 'case', 'catch', 'const', 'continue',
      'debugger', 'default', 'delete', 'do', 'else', 'export', 'false',
      'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'let',
      'new', 'null', 'return', 'switch', 'this', 'throw', 'true', 'try',
      'typeof', 'undefined', 'var', 'void', 'while', 'with', 'yield'
    ]);
  }
}

function _turnOnEditorMode(repl) {
  repl.editorMode = true;
  REPLServer.super_.prototype.setPrompt.call(repl, '');
}

function _turnOffEditorMode(repl) {
  repl.editorMode = false;
  repl.setPrompt(repl._initialPrompt);
}

function defineDefaultCommands(repl) {
  repl.defineCommand('break', {
    help: 'Sometimes you get stuck, this gets you out',
    action: function() {
      this.clearBufferedCommand();
      this.displayPrompt();
    }
  });

  var clearMessage;
  if (repl.useGlobal) {
    clearMessage = 'Alias for .break';
  } else {
    clearMessage = 'Break, and also clear the local context';
  }
  repl.defineCommand('clear', {
    help: clearMessage,
    action: function() {
      this.clearBufferedCommand();
      if (!this.useGlobal) {
        this.outputStream.write('Clearing context...\n');
        this.resetContext();
      }
      this.displayPrompt();
    }
  });

  repl.defineCommand('exit', {
    help: 'Exit the repl',
    action: function() {
      this.close();
    }
  });

  repl.defineCommand('help', {
    help: 'Print this help message',
    action: function() {
      const names = Object.keys(this.commands).sort();
      const longestNameLength = names.reduce(
        (max, name) => Math.max(max, name.length),
        0
      );
      for (var n = 0; n < names.length; n++) {
        var name = names[n];
        var cmd = this.commands[name];
        var spaces = ' '.repeat(longestNameLength - name.length + 3);
        var line = `.${name}${cmd.help ? spaces + cmd.help : ''}\n`;
        this.outputStream.write(line);
      }
      this.displayPrompt();
    }
  });

  repl.defineCommand('save', {
    help: 'Save all evaluated commands in this REPL session to a file',
    action: function(file) {
      try {
        fs.writeFileSync(file, this.lines.join('\n') + '\n');
        this.outputStream.write('Session saved to: ' + file + '\n');
      } catch (e) {
        this.outputStream.write('Failed to save: ' + file + '\n');
      }
      this.displayPrompt();
    }
  });

  repl.defineCommand('load', {
    help: 'Load JS from a file into the REPL session',
    action: function(file) {
      try {
        var stats = fs.statSync(file);
        if (stats && stats.isFile()) {
          _turnOnEditorMode(this);
          var data = fs.readFileSync(file, 'utf8');
          var lines = data.split('\n');
          for (var n = 0; n < lines.length; n++) {
            if (lines[n])
              this.write(`${lines[n]}\n`);
          }
          _turnOffEditorMode(this);
          this.write('\n');
        } else {
          this.outputStream.write('Failed to load: ' + file +
                                  ' is not a valid file\n');
        }
      } catch {
        this.outputStream.write('Failed to load: ' + file + '\n');
      }
      this.displayPrompt();
    }
  });

  repl.defineCommand('editor', {
    help: 'Enter editor mode',
    action() {
      if (!this.terminal) return;
      _turnOnEditorMode(this);
      this.outputStream.write(
        '// Entering editor mode (^D to finish, ^C to cancel)\n');
    }
  });
}

function regexpEscape(s) {
  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

function Recoverable(err) {
  this.err = err;
}
inherits(Recoverable, SyntaxError);
exports.Recoverable = Recoverable;
