#!/usr/bin/python
# 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.

"""Library containing functions to access a remote test device."""

import glob
import logging
import os
import shutil
import stat
import time

from chromite.lib import cros_build_lib
from chromite.lib import osutils
from chromite.lib import timeout_util


_path = os.path.dirname(os.path.realpath(__file__))
TEST_PRIVATE_KEY = os.path.normpath(
    os.path.join(_path, '../ssh_keys/testing_rsa'))
del _path

REBOOT_MARKER = '/tmp/awaiting_reboot'
REBOOT_MAX_WAIT = 120
REBOOT_SSH_CONNECT_TIMEOUT = 2
REBOOT_SSH_CONNECT_ATTEMPTS = 2
CHECK_INTERVAL = 5
DEFAULT_SSH_PORT = 22
SSH_ERROR_CODE = 255


def CompileSSHConnectSettings(ConnectTimeout=30, ConnectionAttempts=4):
  return ['-o', 'ConnectTimeout=%s' % ConnectTimeout,
          '-o', 'ConnectionAttempts=%s' % ConnectionAttempts,
          '-o', 'NumberOfPasswordPrompts=0',
          '-o', 'Protocol=2',
          '-o', 'ServerAliveInterval=10',
          '-o', 'ServerAliveCountMax=3',
          '-o', 'StrictHostKeyChecking=no',
          '-o', 'UserKnownHostsFile=/dev/null', ]


class RemoteAccess(object):
  """Provides access to a remote test machine."""

  def __init__(self, remote_host, tempdir, port=DEFAULT_SSH_PORT,
               debug_level=logging.DEBUG, interactive=True):
    """Construct the object.

    Args:
      remote_host: The ip or hostname of the remote test machine.  The test
                   machine should be running a ChromeOS test image.
      tempdir: A directory that RemoteAccess can use to store temporary files.
               It's the responsibility of the caller to remove it.
      port: The ssh port of the test machine to connect to.
      debug_level: Logging level to use for all RunCommand invocations.
      interactive: If set to False, pass /dev/null into stdin for the sh cmd.
    """
    self.tempdir = tempdir
    self.remote_host = remote_host
    self.port = port
    self.debug_level = debug_level
    self.private_key = os.path.join(tempdir, os.path.basename(TEST_PRIVATE_KEY))
    self.interactive = interactive
    shutil.copyfile(TEST_PRIVATE_KEY, self.private_key)
    os.chmod(self.private_key, stat.S_IRUSR)

  @property
  def target_ssh_url(self):
    return 'root@%s' % self.remote_host

  def _GetSSHCmd(self, connect_settings=None):
    if connect_settings is None:
      connect_settings = CompileSSHConnectSettings()

    cmd = (['ssh', '-p', str(self.port)] +
           connect_settings +
           ['-i', self.private_key])
    if not self.interactive:
      cmd.append('-n')

    return cmd

  def RemoteSh(self, cmd, connect_settings=None, error_code_ok=False,
               ssh_error_ok=False, **kwargs):
    """Run a sh command on the remote device through ssh.

    Args:
      cmd: The command string or list to run.
      connect_settings: The SSH connect settings to use.
      error_code_ok: Does not throw an exception when the command exits with a
                     non-zero returncode.  This does not cover the case where
                     the ssh command itself fails (return code 255).
                     See ssh_error_ok.
      ssh_error_ok: Does not throw an exception when the ssh command itself
                    fails (return code 255).
      **kwargs: See cros_build_lib.RunCommand documentation.

    Returns:
      A CommandResult object.  The returncode is the returncode of the command,
      or 255 if ssh encountered an error (could not connect, connection
      interrupted, etc.)

    Raises:
      RunCommandError when error is not ignored through error_code_ok and
      ssh_error_ok flags.
    """
    kwargs.setdefault('debug_level', self.debug_level)

    ssh_cmd = self._GetSSHCmd(connect_settings)
    if isinstance(cmd, basestring):
      ssh_cmd += [self.target_ssh_url, '--', cmd]
    else:
      ssh_cmd += [self.target_ssh_url, '--'] + cmd

    try:
      result = cros_build_lib.RunCommandCaptureOutput(
          ssh_cmd, **kwargs)
    except cros_build_lib.RunCommandError as e:
      if ((e.result.returncode == SSH_ERROR_CODE and ssh_error_ok) or
          (e.result.returncode and e.result.returncode != SSH_ERROR_CODE
           and error_code_ok)):
        result = e.result
      else:
        raise

    return result

  def LearnBoard(self):
    """Grab the board reported by the remote device.

    in the case of multiple matches, uses the first one.  In the case of no
    entry, returns an empty string.
    """
    result = self.RemoteSh('grep CHROMEOS_RELEASE_BOARD /etc/lsb-release')
    # In the case of multiple matches, use the first one.
    output = result.output.splitlines()
    if len(output) > 1:
      logging.debug('More than one board entry found!  Using the first one.')

    return output[0].strip().partition('=')[-1]

  def _CheckIfRebooted(self):
    """"Checks whether a remote device has rebooted successfully.

    This uses a rapidly-retried SSH connection, which will wait for at most
    about ten seconds. If the network returns an error (e.g. host unreachable)
    the actual delay may be shorter.

    Returns:
      Whether the device has successfully rebooted.
    """
    # In tests SSH seems to be waiting rather longer than would be expected
    # from these parameters. These values produce a ~5 second wait.
    connect_settings = CompileSSHConnectSettings(
        ConnectTimeout=REBOOT_SSH_CONNECT_TIMEOUT,
        ConnectionAttempts=REBOOT_SSH_CONNECT_ATTEMPTS)
    cmd = "[ ! -e '%s' ]" % REBOOT_MARKER
    result = self.RemoteSh(cmd, connect_settings=connect_settings,
                           error_code_ok=True, ssh_error_ok=True)

    errors = {0: 'Reboot complete.',
              1: 'Device has not yet shutdown.',
              255: 'Cannot connect to device; reboot in progress.'}
    if result.returncode not in errors:
      raise Exception('Unknown error code %s returned by %s.'
                      % (result.returncode, cmd))

    logging.info(errors[result.returncode])
    return result.returncode == 0

  def RemoteReboot(self):
    """Reboot the remote device."""
    logging.info('Rebooting %s...', self.remote_host)
    self.RemoteSh('touch %s && reboot' % REBOOT_MARKER)
    time.sleep(CHECK_INTERVAL)
    try:
      timeout_util.WaitForReturnTrue(self._CheckIfRebooted, REBOOT_MAX_WAIT,
                                     period=CHECK_INTERVAL)
    except timeout_util.TimeoutError:
      cros_build_lib.Die('Reboot has not completed after %s seconds; giving up.'
                         % (REBOOT_MAX_WAIT,))

  def Rsync(self, src, dest, to_local=False, follow_symlinks=False,
            inplace=False, verbose=False, sudo=False, **kwargs):
    """Rsync a path to the remote device.

    Rsync a path to the remote device. If |to_local| is set True, it
    rsyncs the path from the remote device to the local machine.

    Args:
      src: The local src directory.
      dest: The remote dest directory.
      to_local: If set, rsync remote path to local path.
      follow_symlinks: If set, transform symlinks into referent
        path. Otherwise, copy symlinks as symlinks.
      inplace: If set, cause rsync to overwrite the dest files in place.  This
        conserves space, but has some side effects - see rsync man page.
      verbose: If set, print more verbose output during rsync file transfer.
      sudo: If set, invoke the command via sudo.
      **kwargs: See cros_build_lib.RunCommand documentation.
    """
    kwargs.setdefault('debug_level', self.debug_level)

    ssh_cmd = ' '.join(self._GetSSHCmd())
    rsync_cmd = ['rsync', '--recursive', '--perms', '--verbose',
                 '--times', '--compress', '--omit-dir-times',
                 '--exclude', '.svn']
    rsync_cmd.append('--copy-links' if follow_symlinks else '--links')
    # In cases where the developer sets up a ssh daemon manually on a device
    # with a dev image, the ssh login $PATH can be incorrect, and the target
    # rsync will not be found.  So we try to provide the right $PATH here.
    rsync_cmd += ['--rsync-path', 'PATH=/usr/local/bin:$PATH rsync']
    if verbose:
      rsync_cmd.append('--progress')
    if inplace:
      rsync_cmd.append('--inplace')

    if to_local:
      rsync_cmd += ['--rsh', ssh_cmd,
                    '[%s]:%s' % (self.target_ssh_url, src), dest]
    else:
      rsync_cmd += ['--rsh', ssh_cmd, src,
                    '[%s]:%s' % (self.target_ssh_url, dest)]

    rc_func = cros_build_lib.RunCommand
    if sudo:
      rc_func = cros_build_lib.SudoRunCommand
    return rc_func(rsync_cmd, print_cmd=verbose, **kwargs)

  def RsyncToLocal(self, *args, **kwargs):
    """Rsync a path from the remote device to the local machine."""
    return self.Rsync(*args, to_local=kwargs.pop('to_local', True), **kwargs)

  def Scp(self, src, dest, recursive=False, verbose=False, debug_level=None,
          sudo=False):
    """Scp a file or directory to the remote device.

    Args:
      src: The local src file or directory.
      dest: The remote dest location.
      recursive: Whether to recursively copy entire directories.
      verbose: If set, print more verbose output during scp file transfer.
      debug_level: See cros_build_lib.RunCommand documentation.
      sudo: If set, invoke the command via sudo.

    Returns:
      A CommandResult object containing the information and return code of
      the scp command.
    """
    if not debug_level:
      debug_level = self.debug_level

    scp_cmd = ['scp', '-p'] + CompileSSHConnectSettings(ConnectTimeout=60)

    if recursive:
      scp_cmd.append('-r')
    if verbose:
      scp_cmd.append('-v')

    scp_cmd += glob.glob(src) + ['%s:%s' % (self.target_ssh_url, dest)]

    rc_func = cros_build_lib.RunCommand
    if sudo:
      rc_func = cros_build_lib.SudoRunCommand

    return rc_func(scp_cmd, debug_level=debug_level, print_cmd=verbose)

  def PipeToRemoteSh(self, producer_cmd, cmd, **kwargs):
    """Run a local command and pipe it to a remote sh command over ssh.

    Args:
      producer_cmd: Command to run locally with its results piped to |cmd|.
      cmd: Command to run on the remote device.
      **kwargs: See RemoteSh for documentation.
    """
    result = cros_build_lib.RunCommandCaptureOutput(producer_cmd,
                                                    stdout_to_pipe=True,
                                                    print_cmd=False)
    return self.RemoteSh(cmd, input=kwargs.pop('input', result.output),
                         **kwargs)


class RemoteDeviceHandler(object):
  """A wrapper of RemoteDevice."""

  def __init__(self, *args, **kwargs):
    """Creates a RemoteDevice object."""
    self.device = RemoteDevice(*args, **kwargs)

  def __enter__(self):
    """Return the temporary directory."""
    return self.device

  def __exit__(self, _type, _value, _traceback):
    """Cleans up the device."""
    self.device.Cleanup()


class RemoteDevice(object):
  """Handling basic SSH communication with a remote device."""

  DEFAULT_WORK_DIR = '/tmp/remote-access'

  def __init__(self, hostname, debug_level=logging.DEBUG, work_dir=None):
    """Initializes a RemoteDevice object.

    Args:
      hostname: The hostname of the device.
      debug_level: Setting debug level for logging.
      work_dir: The default working directory on the device.
    """
    self.hostname = hostname
    # The tempdir is only for storing the rsa key on the host.
    self.tempdir = osutils.TempDir(prefix='ssh-tmp')
    self.agent = self._SetupSSH()
    self.board = self.agent.LearnBoard()
    self.debug_level = debug_level
    # Setup a working directory on the device.
    self.work_dir = self.DEFAULT_WORK_DIR if work_dir is None else work_dir
    self.RunCommand(['rm', '-r', self.work_dir], error_code_ok=True)
    self.RunCommand(['mkdir', '-p', self.work_dir])

  def _SetupSSH(self):
    """Setup the ssh connection with device."""
    return RemoteAccess(self.hostname, self.tempdir.tempdir)

  def Cleanup(self):
    """Clean up the working/temp directories."""
    self.RunCommand(['rm', '-rf', self.work_dir], error_code_ok=True)
    self.tempdir.Cleanup()

  def CopyToDevice(self, src, dest, **kwargs):
    """Copy path to device."""
    self.agent.Rsync(src, dest, **kwargs)

  def CopyFromDevice(self, src, dest, **kwargs):
    """Copy path from device."""
    self.agent.RsyncToLocal(src, dest, **kwargs)

  def CopyFromWorkDir(self, src, dest, **kwargs):
    """Copy path from working directory on the device."""
    self.CopyFromDevice(os.path.join(self.work_dir, src), dest, **kwargs)

  def CopyToWorkDir(self, src, dest='', **kwargs):
    """Copy path to working directory on the device."""
    self.CopyToDevice(src, os.path.join(self.work_dir, dest), **kwargs)

  def PipeOverSSH(self, filepath, cmd, **kwargs):
    """Cat a file and pipe over SSH."""
    producer_cmd = ['cat', filepath]
    return self.agent.PipeToRemoteSh(producer_cmd, cmd, **kwargs)

  def Reboot(self):
    """Reboot the device."""
    self.agent.RemoteReboot()

  def RunCommand(self, cmd, **kwargs):
    """Executes a shell command on the device with output captured."""
    kwargs.setdefault('debug_level', self.debug_level)
    return self.agent.RemoteSh(cmd, **kwargs)
