# -*- coding: utf-8 -*-
# Copyright 2015 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.

"""cros shell: Open a remote shell on the target device."""

from __future__ import print_function

import argparse
import sys

from chromite.cli import command
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import remote_access


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


@command.CommandDecorator('shell')
class ShellCommand(command.CliCommand):
  """Opens a remote shell over SSH on the target device.

  Can be used to start an interactive session or execute a command
  remotely. Interactive sessions can be terminated like a normal SSH
  session using Ctrl+D, `exit`, or `logout`.

  Unlike other `cros` commands, this allows for both SSH key and user
  password authentication. Because a password may be transmitted, the
  known_hosts file is used by default to protect against connecting to
  the wrong device.

  The exit code will be the same as the last executed command.
  """

  EPILOG = """
Examples:
  Start an interactive session:
    cros shell <ip>
    cros shell <user>@<ip>:<port>

  Non-interactive remote command:
    cros shell <ip> -- cat var/log/messages

Quoting can be tricky; the rules are the same as with ssh:
  Special symbols will end the command unless quoted:
    cros shell <ip> -- cat /var/log/messages > log.txt   (saves locally)
    cros shell <ip> -- "cat /var/log/messages > log.txt" (saves remotely)

  One set of quotes is consumed locally, so remote commands that
  require quotes will need double quoting:
    cros shell <ip> -- sh -c "exit 42"    (executes: sh -c exit 42)
    cros shell <ip> -- sh -c "'exit 42'"  (executes: sh -c 'exit 42')
"""

  def __init__(self, options):
    """Initializes ShellCommand."""
    super(ShellCommand, self).__init__(options)
    # ChromiumOSDevice to connect to.
    self.device = None
    # SSH connection settings.
    self.ssh_hostname = None
    self.ssh_port = None
    self.ssh_username = None
    self.ssh_private_key = None
    # Whether to use the SSH known_hosts file or not.
    self.known_hosts = None
    # How to set SSH StrictHostKeyChecking. Can be 'no', 'yes', or 'ask'. Has
    # no effect if |known_hosts| is not True.
    self.host_key_checking = None
    # The command to execute remotely.
    self.command = None

  @classmethod
  def AddParser(cls, parser):
    """Adds a parser."""
    super(cls, ShellCommand).AddParser(parser)
    cls.AddDeviceArgument(parser, positional=True)
    parser.add_argument(
        '--private-key', type='path', default=None,
        help='SSH identify file (private key).')
    parser.add_argument(
        '--no-known-hosts', action='store_false', dest='known_hosts',
        default=True, help='Do not use a known_hosts file.')
    parser.add_argument(
        'command', nargs=argparse.REMAINDER,
        help='(optional) Command to execute on the device.')

  def _ReadOptions(self):
    """Processes options and set variables."""
    self.ssh_hostname = self.options.device.hostname
    self.ssh_username = self.options.device.username
    self.ssh_port = self.options.device.port
    self.ssh_private_key = self.options.private_key
    self.known_hosts = self.options.known_hosts
    # By default ask the user if a new key is found. SSH will still reject
    # modified keys for existing hosts without asking the user.
    self.host_key_checking = 'ask'
    # argparse doesn't always handle -- correctly.
    self.command = self.options.command
    if self.command and self.command[0] == '--':
      self.command.pop(0)

  def _ConnectSettings(self):
    """Generates the correct SSH connect settings based on our state."""
    kwargs = {'NumberOfPasswordPrompts': 2}
    if self.known_hosts:
      # Use the default known_hosts and our current key check setting.
      kwargs['UserKnownHostsFile'] = None
      kwargs['StrictHostKeyChecking'] = self.host_key_checking
    return remote_access.CompileSSHConnectSettings(**kwargs)

  def _UserConfirmKeyChange(self):
    """Asks the user whether it's OK that a host key has changed.

    A changed key can be fairly common during Chrome OS development, so
    instead of outright rejecting a modified key like SSH does, this
    provides some common reasons a key may have changed to help the
    user decide whether it was legitimate or not.

    _StartSsh() must have been called before this function so that
    |self.device| is valid.

    Returns:
      True if the user is OK with a changed host key.
    """
    return cros_build_lib.BooleanPrompt(
        prolog='The host ID for "%s" has changed since last connect.\n'
               'Some common reasons for this are:\n'
               ' - Device powerwash.\n'
               ' - Device flash from a USB stick.\n'
               ' - Device flash using "--clobber-stateful".\n'
               'Otherwise, please verify that this is the correct device'
               ' before continuing.' % self.device.hostname)

  def _StartSsh(self):
    """Starts an SSH session or executes a remote command.

    Also creates |self.device| if it doesn't yet exist. It's created
    once and saved so that if the user wants to use the default device,
    we only have to go through the discovery procedure the first time.

    Requires that _ReadOptions() has already been called to provide the
    SSH configuration.

    Returns:
      The SSH return code.

    Raises:
      SSHConnectionError on SSH connect failure.
    """
    # Create the ChromiumOSDevice the first time through this function.
    if not self.device:
      # Set |base_dir| to None to avoid the SSH setup commands which
      # could require the user to enter a password multiple times. We don't
      # need any of the additional functionality that |base_dir| enables.
      self.device = remote_access.ChromiumOSDevice(
          self.ssh_hostname,
          port=self.ssh_port,
          username=self.ssh_username,
          base_dir=None,
          private_key=self.ssh_private_key,
          ping=False)
    return self.device.BaseRunCommand(
        self.command,
        connect_settings=self._ConnectSettings(),
        check=False,
        stderr=True,
        capture_output=False).returncode

  def Run(self):
    """Runs `cros shell`."""
    self.options.Freeze()
    self._ReadOptions()
    try:
      return self._StartSsh()
    except remote_access.SSHConnectionError as e:
      # Handle a mismatched host key; mismatched keys are a bit of a pain to
      # fix manually since `ssh-keygen -R` doesn't work within the chroot.
      if e.IsKnownHostsMismatch():
        # The full SSH error message has extra info for the user.
        logging.warning('\n%s', e)
        if self._UserConfirmKeyChange():
          remote_access.RemoveKnownHost(self.device.hostname)
          # The user already OK'd so we can skip the additional SSH check.
          self.host_key_checking = 'no'
          return self._StartSsh()
        else:
          return 1
      raise
