// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

lib.rtdep('lib.f', 'lib.fs',
          'nassh.CommandInstance', 'nassh.GoogleRelay',
          'nassh.PreferenceManager');

/**
 * The NaCl-ssh-powered terminal command.
 *
 * This class defines a command that can be run in an hterm.Terminal instance.
 * This command creates an instance of the NaCl-ssh plugin and uses it to
 * communicate with an ssh daemon.
 *
 * If you want to use something other than this NaCl plugin to connect to a
 * remote host (like a shellinaboxd, etc), you'll want to create a brand new
 * command.
 *
 * @param {Object} argv The argument object passed in from the Terminal.
 */
nassh.CommandInstance = function(argv) {
  // Command arguments.
  this.argv_ = argv;

  // Command environment.
  this.environment_ = argv.environment || {};

  // hterm.Terminal.IO instance (can accept another hterm.Terminal.IO instance).
  this.io = argv.terminalIO || null;

  // Relay manager.
  this.relay_ = null;

  // Parsed extension manifest.
  this.manifest_ = null;

  // The HTML5 persistent FileSystem instance for this extension.
  this.fileSystem_ = null;

  // A set of open streams for this instance.
  this.streams_ = new nassh.StreamSet();

  // An HTML5 DirectoryEntry for /.ssh/.
  this.sshDirectoryEntry_ = null;

  // Application ID of auth agent.
  this.authAgentAppID_ = null;

  // Whether the instance is a SFTP instance.
  this.isSftp = argv.isSftp || false;

  // SFTP Client for SFTP instances.
  this.sftpClient = (this.isSftp) ? new nassh.sftp.Client() : null;

  // Mount options for a SFTP instance.
  this.mountOptions = argv.mountOptions || null;

  // Session storage (can accept another hterm tab's sessionStorage).
  this.storage = argv.terminalStorage || window.sessionStorage;

  // Terminal Location reference (can accept another hterm tab's location).
  this.terminalLocation = argv.terminalLocation || document.location;

  // Terminal Window reference (can accept another hterm tab's window).
  this.terminalWindow = argv.terminalWindow || window;

  // Root preference manager.
  this.prefs_ = new nassh.PreferenceManager();

  // Prevent us from reporting an exit twice.
  this.exited_ = false;

  // Buffer for data coming from the terminal.
  this.inputBuffer_ = new nassh.InputBuffer();
};

/**
 * The name of this command used in messages to the user.
 *
 * Perhaps this will also be used by the user to invoke this command if we
 * build a command line shell.
 */
nassh.CommandInstance.prototype.commandName = 'nassh';

/**
 * Static run method invoked by the terminal.
 */
nassh.CommandInstance.run = function(argv) {
  return new nassh.CommandInstance(argv);
};

/**
 * Start the nassh command.
 *
 * Instance run method invoked by the nassh.CommandInstance ctor.
 */
nassh.CommandInstance.prototype.run = function() {
  // Useful for console debugging.
  window.nassh_ = this;

  this.io = this.argv_.io.push();

  // Similar to lib.fs.err, except this logs to the terminal too.
  var ferr = (msg) => {
    return (err) => {
      var ary = Array.apply(null, arguments);
      console.error(msg + ': ' + ary.join(', '));

      this.io.println(nassh.msg('UNEXPECTED_ERROR'));
      this.io.println(err);
    };
  };

  this.prefs_.readStorage(() => {
    this.manifest_ = chrome.runtime.getManifest();

    // Set default window title.
    this.io.print('\x1b]0;' + this.manifest_.name + ' ' +
                    this.manifest_.version + '\x07');

    this.io.println(
        nassh.msg('WELCOME_VERSION',
                  ['\x1b[1m' + this.manifest_.name + '\x1b[m',
                   '\x1b[1m' + this.manifest_.version + '\x1b[m']));

    if (this.manifest_.name.match(/\(tot\)/)) {
      // If we're a tot version, show how old the hterm deps are.
      var htermAge = Math.round(
          (new Date() -
           new Date(lib.resource.getData('hterm/concat/date'))) / 1000);

      this.io.println(
          'hterm ' + lib.resource.getData('hterm/changelog/version') + ': ' +
          (htermAge / 60).toFixed(2) + ' minutes ago.');
    }

    this.io.println(
        nassh.msg('WELCOME_FAQ', ['\x1b[1mhttps://goo.gl/muppJj\x1b[m']));

    if (hterm.windowType != 'popup') {
      var osx = window.navigator.userAgent.match(/Mac OS X/);
      if (!osx) {
        this.io.println('');
        this.io.println(
            nassh.msg('OPEN_AS_WINDOW_TIP',
                      ['\x1b[1mhttps://goo.gl/muppJj\x1b[m']));
        this.io.println('');
      }
    }

    nassh.getFileSystem(onFileSystemFound, ferr('FileSystem init failed'));
  });

  var onFileSystemFound = (fileSystem, sshDirectoryEntry) => {
    this.fileSystem_ = fileSystem;
    this.sshDirectoryEntry_ = sshDirectoryEntry;

    var argstr = this.argv_.argString;

    // This item is set before we redirect away to login to a relay server.
    // If it's set now, it's the first time we're reloading after the redirect.
    var pendingRelay = this.storage.getItem('nassh.pendingRelay');
    this.storage.removeItem('nassh.pendingRelay');

    if (!argstr || (this.storage.getItem('nassh.promptOnReload') &&
                    !pendingRelay)) {
      // If promptOnReload is set or we haven't gotten the destination
      // as an argument then we need to ask the user for the destination.
      //
      // The promptOnReload session item allows us to remember that we've
      // displayed the dialog, so we can re-display it if the user reloads
      // the page.  (Items in sessionStorage are scoped to the tab, kept
      // between page reloads, and discarded when the tab goes away.)
      this.storage.setItem('nassh.promptOnReload', 'yes');

      this.promptForDestination_();
    } else if (!this.connectToArgString(argstr)) {
      this.io.println(nassh.msg('BAD_DESTINATION', [this.argv_.argString]));
      this.exit(1);
    }
  };
};

/**
 * This method moved off to be a static method on nassh, but remains here
 * for js console users who expect to find it here.
 */
nassh.CommandInstance.prototype.exportPreferences = function(onComplete) {
  nassh.exportPreferences(onComplete);
};

/**
 * This method moved off to be a static method on nassh, but remains here
 * for js console users who expect to find it here.
 */
nassh.CommandInstance.prototype.importPreferences = function(
    json, opt_onComplete) {
  nassh.importPreferences(json, opt_onComplete);
};

/**
 * Reconnects to host, using the same CommandInstance.
 *
 * @param {string} argstr The connection ArgString
 */
nassh.CommandInstance.prototype.reconnect = function(argstr) {
  // Terminal reset.
  this.io.print('\x1b[!p');

  this.io = this.argv_.io.push();

  this.plugin_.parentNode.removeChild(this.plugin_);
  this.plugin_ = null;

  this.stdoutAcknowledgeCount_ = 0;
  this.stderrAcknowledgeCount_ = 0;

  this.exited_ = false;

  this.connectToArgString(argstr);
};

/**
 * Removes a file from the HTML5 filesystem.
 *
 * Most likely you want to remove something from the /.ssh/ directory.
 *
 * This command is only here to support unsavory JS console hacks for managing
 * the /.ssh/ directory.
 *
 * @param {string} fullPath The full path to the file to remove.
 */
nassh.CommandInstance.prototype.removeFile = function(fullPath) {
  lib.fs.removeFile(this.fileSystem_.root, '/.ssh/' + identityName);
};

/**
 * Removes a directory from the HTML5 filesystem.
 *
 * Most likely you'll want to remove the entire /.ssh/ directory.
 *
 * This command is only here to support unsavory JS console hacks for managing
 * the /.ssh/ directory.
 *
 * @param {string} fullPath The full path to the file to remove.
 */
nassh.CommandInstance.prototype.removeDirectory = function(fullPath) {
  this.fileSystem_.root.getDirectory(
      fullPath, {},
      function (f) {
        f.removeRecursively(lib.fs.log('Removed: ' + fullPath),
                            lib.fs.err('Error removing' + fullPath));
      },
      lib.fs.log('Error finding: ' + fullPath)
  );
};

/**
 * Remove all known hosts.
 *
 * This command is only here to support unsavory JS console hacks for managing
 * the /.ssh/ directory.
 */
nassh.CommandInstance.prototype.removeAllKnownHosts = function() {
  this.fileSystem_.root.getFile(
      '/.ssh/known_hosts', {create: false},
      function(fileEntry) { fileEntry.remove(function() {}) });
  /*
   * This isn't necessary, but it makes the user interface a little nicer as
   * most people don't realize that "undefined" is what you get from a void
   * javascript function.  Example console output:
   * > term_.command.removeAllKnownHosts()
   * true
   */
  return true;
};

/**
 * Remove a known host by index.
 *
 * This command is only here to support unsavory JS console hacks for managing
 * the /.ssh/ directory.
 *
 * @param {integer} index One-based index of the known host entry to remove.
 */
nassh.CommandInstance.prototype.removeKnownHostByIndex = function(index) {
  var onError = lib.fs.log('Error accessing /.ssh/known_hosts');

  lib.fs.readFile(this.fileSystem_.root, '/.ssh/known_hosts', (contents) => {
    var ary = contents.split('\n');
    ary.splice(index - 1, 1);
    lib.fs.overwriteFile(this.fileSystem_.root, '/.ssh/known_hosts',
                         ary.join('\n'), lib.fs.log('done'), onError);
  }, onError);
};

nassh.CommandInstance.prototype.promptForDestination_ = function(opt_default) {
  var connectDialog = this.io.createFrame(
      lib.f.getURL('/html/nassh_connect_dialog.html'), null);

  connectDialog.onMessage = (event) => {
    event.data.argv.unshift(connectDialog);
    this.dispatchMessage_('connect-dialog', this.onConnectDialog_, event.data);
  };

  connectDialog.show();
};

nassh.CommandInstance.prototype.connectToArgString = function(argstr) {
  var isSftp = this.storage.getItem('nassh.isSftp');
  this.storage.removeItem('nassh.isSftp');

  // Handle profile-id:XXX forms.  These are bookmarkable.
  var ary = argstr.match(/^profile-id:([a-z0-9]+)(\?.*)?/i);
  var rv;
  if (ary) {

    if (isSftp) {
      rv = this.mountProfile(ary[1], ary[2]);
    } else {
      rv = this.connectToProfile(ary[1], ary[2]);
    }

  } else {

    if (isSftp) {
      rv = this.mountDestination(argstr);
    } else {
      rv = this.connectToDestination(argstr);
    }

  }

  return rv;
};

/**
 * Mount a remote host given a profile id. Creates a new SFTP CommandInstance
 * that runs in the background page.
 */
nassh.CommandInstance.prototype.mountProfile = function(
    profileID, querystr) {

  var onReadStorage = () => {
    // TODO(rginda): Soft fail on unknown profileID.
    var prefs = this.prefs_.getProfile(profileID);

    document.querySelector('#terminal').focus();

    if (chrome.extension.getBackgroundPage()
        .nassh.sftp.fsp.sftpInstances[prefs.id]) {
      this.io.println(nassh.msg('ALREADY_MOUNTED_MESSAGE'));
      this.exit(1, true);
      return;
    }

    this.terminalLocation.hash = 'profile-id:' + profileID;
    document.title = prefs.get('description') + ' - ' +
      this.manifest_.name + ' ' + this.manifest_.version;

    var args = {
      argv: {
        terminalIO: this.io,
        terminalStorage: this.storage,
        terminalLocation: this.terminalLocation,
        terminalWindow: this.terminalWindow,
        isSftp: true,
        mountOptions: {
          fileSystemId: prefs.id,
          displayName: prefs.get('description'),
          writable: true
        }
      },
      connectOptions: {
        username: prefs.get('username'),
        hostname: prefs.get('hostname'),
        port: prefs.get('port'),
        relayOptions: prefs.get('relay-options'),
        identity: prefs.get('identity'),
        argstr: prefs.get('argstr'),
        terminalProfile: prefs.get('terminal-profile'),
        authAgentAppID: prefs.get('auth-agent-appid')
      }
    };

    chrome.extension.getBackgroundPage()
      .nassh.sftp.fsp.createSftpInstance(args);
  };

  // Re-read prefs from storage in case they were just changed in the connect
  // dialog.
  this.prefs_.readStorage(onReadStorage);
  return true;
};

/**
 * Initiate a connection to a remote host given a profile id.
 */
nassh.CommandInstance.prototype.connectToProfile = function(
    profileID, querystr) {

  var onReadStorage = () => {
    // TODO(rginda): Soft fail on unknown profileID.
    var prefs = this.prefs_.getProfile(profileID);

    document.querySelector('#terminal').focus();

    // We have to set the url here rather than in connectToArgString, because
    // some callers will come directly to connectToProfile.
    this.terminalLocation.hash = 'profile-id:' + profileID;

    document.title = prefs.get('description') + ' - ' +
      this.manifest_.name + ' ' + this.manifest_.version;

    this.connectTo({
      username: prefs.get('username'),
      hostname: prefs.get('hostname'),
      port: prefs.get('port'),
      relayOptions: prefs.get('relay-options'),
      identity: prefs.get('identity'),
      argstr: prefs.get('argstr'),
      terminalProfile: prefs.get('terminal-profile'),
      authAgentAppID: prefs.get('auth-agent-appid')
    });
  };

  // Re-read prefs from storage in case they were just changed in the connect
  // dialog.
  this.prefs_.readStorage(onReadStorage);

  return true;
};

/**
 * Parse the destination string.
 *
 * This also handles ssh:// URIs.
 *
 * @param {string} destination A string of the form username@host[:port].
 * @return {boolean|Object} False if we couldn't parse the destination.
 *     An object if we were able to parse out the connect settings.
 */
nassh.CommandInstance.prototype.parseDestination = function(destination) {
  // Deal with ssh:// links.  They are encoded with % hexadecimal sequences.
  // Note: These might be ssh: or ssh://, so have to deal with that.
  if (destination.startsWith('uri:')) {
    // Strip off the "uri:" before decoding it.
    destination = unescape(destination.substr(4));
    if (!destination.startsWith('ssh:'))
      return false;

    // Strip off the "ssh:" prefix.
    destination = destination.substr(4);
    // Strip off the "//" if it exists.
    if (destination.startsWith('//'))
      destination = destination.substr(2);
  }

  // Parse the connection string.
  var ary = destination.match(
      //|user |@| [  ipv6       %zoneid   ]| host |   :port      @ relay options
      /^([^@]+)@(\[[:0-9a-f]+(?:%[^\]]+)?\]|[^:@]+)(?::(\d+))?(?:@([^:]+)(?::(\d+))?)?$/);

  if (!ary)
    return false;

  var username = ary[1];
  var hostname = ary[2];
  var port = ary[3];

  // If it's IPv6, remove the brackets.
  if (hostname.startsWith('[') && hostname.endsWith(']'))
    hostname = hostname.substr(1, hostname.length - 2);

  var relayOptions = '';
  if (ary[4]) {
    relayOptions = '--proxy-host=' + ary[4];

    if (ary[5])
      relayOptions += ' --proxy-port=' + ary[5];
  }

  return {
      username: username,
      hostname: hostname,
      port: port,
      relayOptions: relayOptions,
      destination: destination,
  };
};

/**
 * Initiate a connection to a remote host given a destination string.
 *
 * @param {string} destination A string of the form username@host[:port].
 * @return {boolean} True if we were able to parse the destination string,
 *     false otherwise.
 */
nassh.CommandInstance.prototype.connectToDestination = function(destination) {
  if (destination == 'crosh') {
    this.terminalLocation.href = 'crosh.html';
    return true;
  }

  var rv = this.parseDestination(destination);
  if (rv === false)
    return rv;

  // We have to set the url here rather than in connectToArgString, because
  // some callers may come directly to connectToDestination.
  this.terminalLocation.hash = rv.destination;

  return this.connectTo(rv);
};

/**
 * Mount a remote host given a destination string.
 *
 * @param {string} destination A string of the form username@host[:port].
 * @return {boolean} True if we were able to parse the destination string,
 *     false otherwise.
 */
nassh.CommandInstance.prototype.mountDestination = function(destination) {
  var rv = this.parseDestination(destination);
  if (rv === false)
    return rv;

  // We have to set the url here rather than in connectToArgString, because
  // some callers may come directly to connectToDestination.
  this.terminalLocation.hash = rv.destination;

  var args = {
    argv: {
      terminalIO: this.io,
      terminalStorage: this.storage,
      terminalLocation: this.terminalLocation,
      terminalWindow: this.terminalWindow,
      isSftp: true,
      mountOptions: {
        fileSystemId: rv.username + rv.hostname,
        displayName: rv.username + rv.hostname,
        writable: true
      }
    },
    connectOptions: rv,
  };

  return chrome.extension.getBackgroundPage().
    nassh.sftp.fsp.createSftpInstance(args);
};

/**
 * Initiate a connection to a remote host.
 *
 * @param {string} username The username to provide.
 * @param {string} hostname The hostname or IP address to connect to.
 * @param {string|integer} opt_port The optional port number to connect to.
 * @return {boolean} False if there was some trouble with the parameters, true
 *     otherwise.
 */
nassh.CommandInstance.prototype.connectTo = function(params) {
  if (!(params.username && params.hostname))
    return false;

  if (params.hostname == '>crosh') {
    // TODO: This will need to be done better.  document.location changes don't
    // work in v2 apps.
    this.terminalLocation.href = 'crosh.html';
    return;
  }

  if (params.relayOptions) {
    var relay = new nassh.GoogleRelay(this.io, params.relayOptions,
                                      this.terminalLocation,
                                      this.storage);

    // TODO(rginda): The `if (relay.proxyHost)` test is part of a goofy hack
    // to add the --ssh-agent param to the relay-options pref.  --ssh-agent has
    // no business being a relay option, but it's the best of the bad options.
    // In the future perfect world, 'relay-options' would probably be a generic
    // 'nassh-options' value and the parsing code wouldn't be part of the relay
    // class.
    //
    // For now, we let the relay code parse the options, and if the resulting
    // options don't include a proxyHost then we don't have an actual relay.
    // We may have a --ssh-agent argument though, which we'll pull out of
    // the relay object later.
    if (relay.proxyHost) {
      this.relay_ = relay;

      this.io.println(nassh.msg(
          'INITIALIZING_RELAY',
          [this.relay_.proxyHost + ':' + this.relay_.proxyPort]));

      if (!this.relay_.init()) {
        // A false return value means we have to redirect to complete
        // initialization.  Bail out of the connect for now.  We'll resume it
        // when the relay is done with its redirect.

        // If we're going to have to redirect for the relay then we should make
        // sure not to re-prompt for the destination when we return.
        this.storage.setItem('nassh.pendingRelay', 'yes');

        // If we're trying to mount an SFTP connection, remember it.
        if (this.isSftp) {
          this.storage.setItem('nassh.isSftp', 'yes');
        }

        this.relay_.redirect();
        return true;
      }
    }

    if (relay.options['--ssh-agent'])
      params.authAgentAppID = relay.options['--ssh-agent'];
  }

  this.authAgentAppID_ = params.authAgentAppID;

  this.io.setTerminalProfile(params.terminalProfile || 'default');

  // TODO(rginda): The "port" parameter was removed from the CONNECTING message
  // on May 9, 2012, however the translations haven't caught up yet.  We should
  // remove the port parameter here once they do.
  this.io.println(nassh.msg('CONNECTING',
                            [params.username + '@' + params.hostname,
                             (params.port || '??')]));
  this.io.onVTKeystroke = this.onVTKeystroke_.bind(this);
  this.io.sendString = this.sendString_.bind(this);
  this.io.onTerminalResize = this.onTerminalResize_.bind(this);

  var argv = {};
  argv.terminalWidth = this.io.terminal_.screenSize.width;
  argv.terminalHeight = this.io.terminal_.screenSize.height;
  argv.useJsSocket = !!this.relay_;
  argv.environment = this.environment_;
  argv.writeWindow = 8 * 1024;

  argv.arguments = ['-C'];  // enable compression

  if (params.authAgentAppID) {
    argv.authAgentAppID = params.authAgentAppID;
    argv.arguments.push('-A');  // Force agent forwarding.
  }

  // Disable IP address check for connection through proxy.
  if (argv.useJsSocket)
    argv.arguments.push('-o CheckHostIP=no');

  var commandArgs;
  if (params.argstr) {
    var ary = params.argstr.match(/^(.*?)(?:(?:^|\s+)(?:--\s+(.*)))?$/);
    if (ary) {
      if (ary[1])
        argv.arguments = argv.arguments.concat(ary[1].trim().split(/\s+/));
      if (ary[2])
        commandArgs = ary[2].trim();
    }
  }

  if (params.identity)
    argv.arguments.push('-i/.ssh/' + params.identity);
  if (params.port)
    argv.arguments.push('-p' + params.port);

  argv.arguments.push(params.username + '@' + params.hostname);

  // If this is a SFTP connection, the remote command args don't make sense,
  // and will actually cause a problem.  Since it's easy to do, just ignore
  // them here.
  if (this.isSftp) {
    argv.arguments.push('-s', 'sftp');
  } else if (commandArgs) {
    argv.arguments.push(commandArgs);
  }

  this.initPlugin_(() => {
      if (!nassh.v2)
        this.terminalWindow.addEventListener('beforeunload', this.onBeforeUnload);

      this.sendToPlugin_('startSession', [argv]);
      if (this.isSftp) {
        this.sftpClient.initConnection(this.plugin_);
      }
    });

  return true;
};

/**
 * Dispatch a "message" to one of a collection of message handlers.
 */
nassh.CommandInstance.prototype.dispatchMessage_ = function(
    desc, handlers, msg) {
  if (msg.name in handlers) {
    handlers[msg.name].apply(this, msg.argv);
  } else {
    console.log('Unknown "' + desc + '" message: ' + msg.name);
  }
};

nassh.CommandInstance.prototype.initPlugin_ = function(onComplete) {
  var onPluginLoaded = () => {
    this.io.println(nassh.msg('PLUGIN_LOADING_COMPLETE'));
    onComplete();
  };

  this.io.print(nassh.msg('PLUGIN_LOADING'));

  this.plugin_ = window.document.createElement('embed');
  this.plugin_.style.cssText =
      ('position: absolute;' +
       'top: -99px' +
       'width: 0;' +
       'height: 0;');

  var pluginURL = '../plugin/pnacl/ssh_client.nmf';

  this.plugin_.setAttribute('src', pluginURL);
  this.plugin_.setAttribute('type', 'application/x-nacl');
  this.plugin_.addEventListener('load', onPluginLoaded);
  this.plugin_.addEventListener('message', this.onPluginMessage_.bind(this));
  this.plugin_.addEventListener('crash', (ev) => {
    console.log('plugin crashed');
    this.exit(-1);
  });

  document.body.insertBefore(this.plugin_, document.body.firstChild);
};

/**
 * Callback when the user types into the terminal.
 *
 * @param {string} data The input from the terminal.
 */
nassh.CommandInstance.prototype.onVTKeystroke_ = function(data) {
  this.inputBuffer_.write(data);
};

/**
 * Helper function to create a TTY stream.
 *
 * @param {integer} fd The file descriptor index.
 * @param {boolean} allowRead True if this stream can be read from.
 * @param {boolean} allowWrite True if this stream can be written to.
 * @param {function} onOpen Callback to call when the stream is opened.
 *
 * @return {Object} The newly created stream.
 */
nassh.CommandInstance.prototype.createTtyStream = function(
    fd, allowRead, allowWrite, onOpen) {
  var arg = {
    fd: fd,
    allowRead: allowRead,
    allowWrite: allowWrite,
    inputBuffer: this.inputBuffer_,
    io: this.io
  };

  var stream = this.streams_.openStream(nassh.Stream.Tty, fd, arg, onOpen);
  if (allowRead) {
    var onDataAvailable = (isAvailable) => {
      // Send current read status to plugin.
      this.sendToPlugin_('onReadReady', [fd, isAvailable]);
    };

    this.inputBuffer_.onDataAvailable.addListener(onDataAvailable);

    stream.onClose = (reason) => {
      this.inputBuffer_.onDataAvailable.removeListener(onDataAvailable);
      this.sendToPlugin_('onClose', [fd, reason]);
    };
  }

  return stream;
};

/**
 * Send a message to the nassh plugin.
 *
 * @param {string} name The name of the message to send.
 * @param {Array} arguments The message arguments.
 */
nassh.CommandInstance.prototype.sendToPlugin_ = function(name, args) {
  var str = JSON.stringify({name: name, arguments: args});

  this.plugin_.postMessage(str);
};

/**
 * Send a string to the remote host.
 *
 * @param {string} string The string to send.
 */
nassh.CommandInstance.prototype.sendString_ = function(string) {
  this.inputBuffer_.write(string);
};

/**
 * Notify plugin about new terminal size.
 *
 * @param {string|integer} terminal width.
 * @param {string|integer} terminal height.
 */
nassh.CommandInstance.prototype.onTerminalResize_ = function(width, height) {
  this.sendToPlugin_('onResize', [Number(width), Number(height)]);
};

/**
 * Exit the nassh command.
 */
nassh.CommandInstance.prototype.exit = function(code, noReconnect) {
  if (this.exited_) {
    return;
  }

  this.exited_ = true;

  if (!nassh.v2)
    this.terminalWindow.removeEventListener('beforeunload', this.onBeforeUnload_);

  // Close all streams upon exit.
  this.streams_.closeAllStreams();

  if (this.isSftp) {
    if (nassh.sftp.fsp.sftpInstances[this.mountOptions.fileSystemId]) {
      delete nassh.sftp.fsp.sftpInstances[this.mountOptions.fileSystemId];
    }

    console.log(nassh.msg('DISCONNECT_MESSAGE', [code]));
    return;
  } else {
    this.io.println(nassh.msg('DISCONNECT_MESSAGE', [code]));
  }

  if (noReconnect) {
    this.io.println(nassh.msg('CONNECT_OR_EXIT_MESSAGE'));
  } else {
    this.io.println(nassh.msg('RECONNECT_MESSAGE'));
  }

  this.io.onVTKeystroke = (string) => {
    var ch = string.toLowerCase();
    switch (ch) {
      case 'c':
      case '\x12': // ctrl-r
        nassh.reloadWindow();
        break;

      case 'e':
      case 'x':
      case '\x1b': // ESC
      case '\x17': // ctrl-w
        this.io.pop();
        if (this.argv_.onExit) {
          this.argv_.onExit(code);
        }
        break;

      case 'r':
      case ' ':
      case '\x0d': // enter
        if (!noReconnect) {
          this.reconnect(this.terminalLocation.hash.substr(1));
        }
    }
  };
};

nassh.CommandInstance.prototype.onBeforeUnload_ = function(e) {
  if (hterm.windowType == 'popup')
    return;

  var msg = nassh.msg('BEFORE_UNLOAD');
  e.returnValue = msg;
  return msg;
};

/**
 * Called when the plugin sends us a message.
 *
 * Plugin messages are JSON strings rather than arbitrary JS values.  They
 * also use "arguments" instead of "argv".  This function translates the
 * plugin message into something dispatchMessage_ can digest.
 */
nassh.CommandInstance.prototype.onPluginMessage_ = function(e) {
  var msg = JSON.parse(e.data);
  msg.argv = msg.arguments;
  this.dispatchMessage_('plugin', this.onPlugin_, msg);
};

/**
 * Connect dialog message handlers.
 */
nassh.CommandInstance.prototype.onConnectDialog_ = {};

/**
 * Sent from the dialog when the user chooses to mount a profile.
 */
nassh.CommandInstance.prototype.onConnectDialog_.mountProfile = function(
    dialogFrame, profileID) {
  dialogFrame.close();

  if (!this.mountProfile(profileID)) {
    this.promptForDestination_();
  }
};

/**
 * Sent from the dialog when the user chooses to connect to a profile.
 */
nassh.CommandInstance.prototype.onConnectDialog_.connectToProfile = function(
    dialogFrame, profileID) {
  dialogFrame.close();

  if (!this.connectToProfile(profileID))
    this.promptForDestination_();
};

/**
 * Plugin message handlers.
 */
nassh.CommandInstance.prototype.onPlugin_ = {};

/**
 * Log a message from the plugin.
 */
nassh.CommandInstance.prototype.onPlugin_.printLog = function(str) {
  console.log('plugin log: ' + str);
};

/**
 * Plugin has exited.
 */
nassh.CommandInstance.prototype.onPlugin_.exit = function(code) {
  console.log('plugin exit: ' + code);
  this.sendToPlugin_('onExitAcknowledge', []);
  this.exit(code);
};

/**
 * Plugin wants to open a file.
 *
 * The plugin leans on JS to provide a persistent filesystem, which we do via
 * the HTML5 Filesystem API.
 *
 * In the future, the plugin may handle its own files.
 */
nassh.CommandInstance.prototype.onPlugin_.openFile = function(fd, path, mode) {
  var isAtty = true;
  var onOpen = (success) => {
    this.sendToPlugin_('onOpenFile', [fd, success, isAtty]);
  }

  var DEV_TTY = '/dev/tty';
  var DEV_STDIN = '/dev/stdin';
  var DEV_STDOUT = '/dev/stdout';
  var DEV_STDERR = '/dev/stderr';

  if (path == '/dev/random') {
    var stream = this.streams_.openStream(nassh.Stream.Random,
      fd, path, onOpen);
    stream.onClose = (reason) => {
      this.sendToPlugin_('onClose', [fd, reason]);
    };
  } else if (path == DEV_TTY || path == DEV_STDIN || path == DEV_STDOUT ||
             path == DEV_STDERR) {
    var allowRead = path == DEV_STDIN || path == DEV_TTY;
    var allowWrite = path == DEV_STDOUT || path == DEV_STDERR || path == DEV_TTY;
    if (this.isSftp && path != DEV_TTY) {
      isAtty = false;
    }
    var stream = this.createTtyStream(fd, allowRead, allowWrite, onOpen);
  } else {
    this.sendToPlugin_('onOpenFile', [fd, false, false]);
  }
};

nassh.CommandInstance.prototype.onPlugin_.openSocket = function(fd, host, port) {
  var stream = null;

  if (port == 0 && host == this.authAgentAppID_) {
    // Request for auth-agent connection.
    stream = this.streams_.openStream(nassh.Stream.SSHAgentRelay, fd,
      {authAgentAppID: this.authAgentAppID_}, (success) => {
        this.sendToPlugin_('onOpenSocket', [fd, success, false]);
      });
  } else {
    // Regular relay connection request.
    if (!this.relay_) {
      this.sendToPlugin_('onOpenSocket', [fd, false, false]);
      return;
    }

    stream = this.relay_.openSocket(fd, host, port, this.streams_,
      (success) => {
        this.sendToPlugin_('onOpenSocket', [fd, success, false]);
      });
  }

  stream.onDataAvailable = (data) => {
    this.sendToPlugin_('onRead', [fd, data]);
  };

  stream.onClose = (reason) => {
    this.sendToPlugin_('onClose', [fd, reason]);
  };
};

/**
 * Plugin wants to write some data to a file descriptor.
 *
 * This is used to write to HTML5 Filesystem files.
 */
nassh.CommandInstance.prototype.onPlugin_.write = function(fd, data) {
  if (this.isSftp && !this.sftpClient.isInitialised
      && isSftpInitResponse(data)) {
    this.onSftpInitialised();
  }

  var stream = this.streams_.getStreamByFd(fd);

  if (!stream) {
    console.warn('Attempt to write to unknown fd: ' + fd);
    return;
  }

  stream.asyncWrite(data, (writeCount) => {
    this.sendToPlugin_('onWriteAcknowledge', [fd, writeCount]);
  }, 100);
};

/**
 * Checks to see if the plugin responded with a VERSION SFTP packet.
 */
function isSftpInitResponse(data) {
  var packet = new nassh.sftp.Packet(atob(data));
  var packetLength = packet.getUint32();
  var packetType = packet.getUint8();

  // returns true if the packet has a valid length and is of type VERSION (2).
  return packetLength == packet.getLength() - 4 && packetType == 2;
}

/**
 * SFTP Initialization handler. Mounts the SFTP connection as a file system.
 */
nassh.CommandInstance.prototype.onSftpInitialised = function() {
  // Mount file system.
  chrome.fileSystemProvider.mount(this.mountOptions);

  // Add this instance to list of SFTP instances.
  nassh.sftp.fsp.sftpInstances[this.mountOptions.fileSystemId] = this;

  // Update stdout stream to output to the SFTP Client.
  this.streams_.getStreamByFd(1).setIo(this.sftpClient);

  this.io.showOverlay(nassh.msg('MOUNTED_MESSAGE') + ' '
                      + nassh.msg('CONNECT_OR_EXIT_MESSAGE'), null);

  this.io.onVTKeystroke = (string) => {
    var ch = string.toLowerCase();
    switch (ch) {
      case 'c':
      case '\x12': // ctrl-r
        this.terminalLocation.hash = '';
        this.terminalLocation.reload();
        break;

      case 'e':
      case 'x':
      case '\x1b': // ESC
      case '\x17': // ctrl-w
        this.terminalWindow.close();
    }
  };
}

/**
 * Plugin wants to read from a fd.
 */
nassh.CommandInstance.prototype.onPlugin_.read = function(fd, size) {
  var stream = this.streams_.getStreamByFd(fd);

  if (!stream) {
    console.warn('Attempt to read from unknown fd: ' + fd);
    return;
  }

  stream.asyncRead(size, (b64bytes) => {
    this.sendToPlugin_('onRead', [fd, b64bytes]);
  });
};

/**
 * Notify the plugin that data is available to read.
 */
nassh.CommandInstance.prototype.onPlugin_.isReadReady = function(fd) {
  var stream = this.streams_.getStreamByFd(fd);

  if (!stream) {
    console.warn('Attempt to call isReadReady from unknown fd: ' + fd);
    return;
  }

  var rv = stream.isReadReady();
  this.sendToPlugin_('onIsReadReady', [fd, rv]);
};

/**
 * Plugin wants to close a file descriptor.
 */
nassh.CommandInstance.prototype.onPlugin_.close = function(fd) {
  var stream = this.streams_.getStreamByFd(fd);

  if (!stream) {
    console.warn('Attempt to close unknown fd: ' + fd);
    return;
  }

  this.streams_.closeStream(fd);
};
