#!/usr/bin/env python2.7
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import re
import subprocess
import time

from buildenv import BuildEnv
from host import Host


class Device(object):
    """Represents a Fuchsia device running a specific build.

       This class abstracts the details of remotely running commands and
       transferring data to and from the device.

       Attributes:
         buildenv:         The associated BuildEnv object for this device.
         name:             The device's name, as in `fx list-devices`.
         addr:             The device's IPv6 address.
         port:             TCP port number that sshd is listening on.
         ssh_config:       Path to an SSH configuration file.
         ssh_identity:     Path to an SSH identity file.
         ssh_options:      SSH options as in an SSH configuration file.
         ssh_verbosity:    How verbose SSH processes are, from 0 to 3.
    """

    def __init__(self, factory, name=None, addr=None):
        assert factory, 'Factory for device not set.'
        self._factory = factory
        self._name = name
        self._addr = addr
        self._ssh_options = {}
        self._ssh_config_options = []
        self._ssh_verbosity = 0
        self._reachable = None
        self._urls = None

    @property
    def buildenv(self):
        """The associated BuildEnv object for this device."""
        return self._factory.buildenv

    @property
    def host(self):
        """Alias for buildenv.host."""
        return self._factory.host

    @property
    def addr(self):
        """IPv6 address of the device."""
        if not self._addr:
            self._addr = self.buildenv.find_device(self._name)
        return self._addr

    @property
    def port(self):
        """The TCP port number that the device's sshd is listening on."""
        return int(self._ssh_options.get('P', '22'))

    @port.setter
    def port(self, port):
        self._ssh_options['P'] = str(port)

    @property
    def ssh_config(self):
        """Path to an SSH configuration file."""
        return self._ssh_options.get('F', None)

    @ssh_config.setter
    def ssh_config(self, ssh_config):
        if not self.host.isfile(ssh_config):
            raise ValueError(
                'Invalid SSH configuration file: {}'.format(ssh_config))
        self._ssh_options['F'] = ssh_config

    @property
    def ssh_identity(self):
        """Path to an SSH identity file."""
        return self._ssh_options.get('i', None)

    @ssh_identity.setter
    def ssh_identity(self, ssh_identity):
        if not self.host.isfile(ssh_identity):
            raise ValueError(
                'Invalid SSH identity file: {}'.format(ssh_identity))
        self._ssh_options['i'] = ssh_identity

    @property
    def ssh_options(self):
        """SSH configuration options, as in an SSH configuration file."""
        return self._ssh_config_options

    @ssh_options.setter
    def ssh_options(self, ssh_options):
        self._ssh_config_options = ssh_options

    @property
    def ssh_verbosity(self):
        """How verbose SSH processes are, from 0 to 3."""
        return self._ssh_verbosity

    @ssh_verbosity.setter
    def ssh_verbosity(self, ssh_verbosity):
        if ssh_verbosity < 0 or ssh_verbosity > 3:
            raise ValueError('Invalid ssh_verbosity: {}'.format(ssh_verbosity))
        self._ssh_verbosity = ssh_verbosity

    @property
    def reachable(self):
        """Indicates if the device is reachable via SSH."""
        if self._reachable == None:
            self._reachable = self.ssh(['true']).call() == 0
        return self._reachable

    def configure(self):
        """Sets the defaults for this device."""
        self.ssh_config = self.buildenv.abspath(
            self.buildenv.build_dir, 'ssh-keys', 'ssh_config')

    def ssh_opts(self):
        """Returns the SSH executable and options."""
        ssh_options = []

        # Flags
        if self._ssh_verbosity != 0:
            ssh_options += ['-{}'.format('v' * self._ssh_verbosity)]

        # Options
        for key, val in sorted(self._ssh_options.iteritems()):
            ssh_options += ['-{}'.format(key), val]

        # Configuration options
        for val in sorted(self._ssh_config_options):
            ssh_options += ['-o', val]

        return ssh_options

    def ssh(self, args, **kwargs):
        """Creates a Process with added SSH arguments.

    Provides the additional arguments to handle connecting the device and other
    SSH options. The returned Process represents a command that can be run on
    the remote device.

    Args:
      cmdline: List of command line arguments to execute on device
      kwargs: Same as for subprocess.Popen

    Returns:
      A Process object.
    """
        args = ['ssh'] + self.ssh_opts() + [self.addr] + args
        process = self.host.create_process(args, **kwargs)

        # Explicitly prevent the subprocess from inheriting our stdin
        if not process.stdin:
            process.stdin = Host.DEVNULL

        return process

    def has_cs_info(self, url, refresh=False):
        """Returns whether a component given by a URL is running.

           Relative to the duration of most "fx fuzz" commands, the SSH
           invocation to get component status is fairly expensive. Most
           prcoesses won't meaningfully change during or command (or will only
           change as a result of it). Thus, it makes sense to generally cache
           the `cs info` results. This can lead to small degree of inaccuracy, e.g.
           "fx fuzz check" reporting a fuzzer as "RUNNING" when it stops
           between the command invocation and the display of results. This is
           unlikely (and inconseuqential) enough in normal operation to be
           deemed acceptable.

           If an accurate status is needed, e.g. as part of a long-lived command
           like Fuzzer.monitor(), "refresh" can be set to True to re-run the SSH
           command.
        """
        if not self.reachable:
            return False
        if self._urls == None or refresh:
            self._urls = []
            out = self.ssh(['cs', 'info']).check_output()
            pat = re.compile(r'^URL: (?P<url>.*)')
            for line in str(out).split('\n'):
                match = pat.match(line)
                if not match:
                    continue
                self._urls.append(match.group('url'))
        return url in self._urls

    def isfile(self, pathname):
        """Returns true for files that exist on the device."""
        return self.ssh(['test', '-f', pathname]).call() == 0

    def isdir(self, pathname):
        """Returns true for directories that exist on the device."""
        return self.ssh(['test', '-d', pathname]).call() == 0

    def ls(self, pathname):
        """Returns a map of file names to sizes for the given path."""
        results = {}
        try:
            process = self.ssh(['ls', '-l', pathname])
            # Suppress error messages
            process.stderr = Host.DEVNULL
            out = process.check_output()
            for line in str(out).split('\n'):
                # Line ~= '-rw-r--r-- 1 0 0 8192 Mar 18 22:02 some-name'
                parts = line.split()
                if len(parts) > 8:
                    results[' '.join(parts[8:])] = int(parts[4])
        except subprocess.CalledProcessError as e:
            # The returncode is 1 when the file or directory is not found (see
            # sbase/ls.c); for our purposes, this is not an error, but we don't
            # want to mask other errors such as `ls` itself not being found.
            if e.returncode != 1:
                raise
        return results

    def mkdir(self, pathname):
        """Make a directory on the device."""
        cmd = ['mkdir', '-p', pathname]
        self.ssh(cmd).check_call()

    def remove(self, pathname, recursive=False):
        """Removes a file or directory from the device."""
        if recursive:
            cmd = ['rm', '-rf', pathname]
        else:
            cmd = ['rm', '-f', pathname]
        self.ssh(cmd).check_call()

    def dump_log(self, *args):
        """Retrieve a syslog from the device."""
        cmd = ['log_listener', '--dump_logs', 'yes', '--pretty', 'no'
              ] + list(args)
        return self.ssh(cmd).check_output()

    def guess_pid(self):
        """Tries to guess the fuzzer process ID from the device syslog.

        This will assume the last line which contained one of the strings
        '{{{reset}}}', 'libFuzzer', or 'Sanitizer' is the fuzzer process, and
        try to extract its PID.

        Returns:
          The PID of the process suspected to be the fuzzer, or -1 if no
          suitable candidate was found.
        """
        out = self.dump_log('--only', 'reset,Fuzzer,Sanitizer')
        pid = -1
        if out:
            for line in out.split('\n'):
                # Log lines are like '[timestamp][pid][tid][name] data'
                parts = line.split('][')
                if len(parts) > 2:
                    pid = int(parts[1])
        return pid

    def scp_rpath(self, pathname):
        """Returns an scp-style pathname argument for a remote path."""
        return '[{}]:{}'.format(self.addr, pathname)

    def fetch(self, host_dst, *args):
        """Copies files on the device to a directory on the host.

           The host directory is given by the first argument.

           This does not retry, even if the fetch is racing the file creation.
           In this case, the correct approach is to use some other signal to
           determine when the file(s) should be fetched. See Fuzzer._launch()
           for an example.
        """
        if not args:
            raise ValueError('No source files specified')

        if not self.host.isdir(host_dst):
            self.host.error('No such directory: {}'.format(host_dst))

        device_srcs = []
        for device_src in args:
            device_srcs.append(self.scp_rpath(device_src))

        cmd = ['scp'] + self.ssh_opts() + device_srcs + [host_dst]
        self.host.create_process(cmd).check_call()

    def store(self, device_dst, *args):
        """Copies files on the host to a directory on the device.

           The device directory is given by the first argument.
        """
        self.mkdir(device_dst)
        device_dst = self.scp_rpath(device_dst)

        host_srcs = []
        for host_src in args:
            host_srcs += self.host.glob(host_src)

        if not host_srcs:
            self.host.error('No matching files: "{}".'.format(' '.join(args)))

        cmd = ['scp'] + self.ssh_opts() + host_srcs + [device_dst]
        self.host.create_process(cmd).check_call()
        return host_srcs
