# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from builtins import str
from past.builtins import basestring

import logging
import psutil
import subprocess
import time
import threading

from mobly import utils

# Command to use for running ADB commands.
ADB = 'adb'

# adb gets confused if we try to manage bound ports in parallel, so anything to
# do with port forwarding must happen under this lock.
ADB_PORT_LOCK = threading.Lock()

# Qualified class name of the default instrumentation test runner.
DEFAULT_INSTRUMENTATION_RUNNER = 'com.android.common.support.test.runner.AndroidJUnitRunner'

# Adb getprop call should never take too long.
DEFAULT_GETPROP_TIMEOUT_SEC = 5
DEFAULT_GETPROPS_ATTEMPTS = 3
DEFAULT_GETPROPS_RETRY_SLEEP_SEC = 1


class Error(Exception):
    """Base error type for adb proxy module."""


class AdbError(Error):
    """Raised when an adb command encounters an error.

    Args:
        cmd: list of strings, the adb command executed.
        stdout: byte string, the raw stdout of the command.
        stderr: byte string, the raw stderr of the command.
        ret_code: int, the return code of the command.
        serial: string, the serial of the device the command is executed on.
            This is an empty string if the adb command is not specific to a
            device.
    """
    def __init__(self, cmd, stdout, stderr, ret_code, serial=''):
        self.cmd = cmd
        self.stdout = stdout
        self.stderr = stderr
        self.ret_code = ret_code
        self.serial = serial

    def __str__(self):
        return ('Error executing adb cmd "%s". ret: %d, stdout: %s, stderr: %s'
                ) % (utils.cli_cmd_to_string(
                    self.cmd), self.ret_code, self.stdout, self.stderr)


class AdbTimeoutError(Error):
    """Raised when an command did not complete within expected time.

    Args:
        cmd: list of strings, the adb command that timed out
        timeout: float, the number of seconds passed before timing out.
        serial: string, the serial of the device the command is executed on.
            This is an empty string if the adb command is not specific to a
            device.
    """
    def __init__(self, cmd, timeout, serial=''):
        self.cmd = cmd
        self.timeout = timeout
        self.serial = serial

    def __str__(self):
        return 'Timed out executing command "%s" after %ss.' % (
            utils.cli_cmd_to_string(self.cmd), self.timeout)


def list_occupied_adb_ports():
    """Lists all the host ports occupied by adb forward.

    This is useful because adb will silently override the binding if an attempt
    to bind to a port already used by adb was made, instead of throwing binding
    error. So one should always check what ports adb is using before trying to
    bind to a port with adb.

    Returns:
        A list of integers representing occupied host ports.
    """
    out = AdbProxy().forward('--list')
    clean_lines = str(out, 'utf-8').strip().split('\n')
    used_ports = []
    for line in clean_lines:
        tokens = line.split(' tcp:')
        if len(tokens) != 3:
            continue
        used_ports.append(int(tokens[1]))
    return used_ports


class AdbProxy(object):
    """Proxy class for ADB.

    For syntactic reasons, the '-' in adb commands need to be replaced with
    '_'. Can directly execute adb commands on an object:
    >> adb = AdbProxy(<serial>)
    >> adb.start_server()
    >> adb.devices() # will return the console output of "adb devices".

    By default, command args are expected to be an iterable which is passed
    directly to subprocess.Popen():
    >> adb.shell(['echo', 'a', 'b'])

    This way of launching commands is recommended by the subprocess
    documentation to avoid shell injection vulnerabilities and avoid having to
    deal with multiple layers of shell quoting and different shell environments
    between different OSes.

    If you really want to run the command through the system shell, this is
    possible by supplying shell=True, but try to avoid this if possible:
    >> adb.shell('cat /foo > /tmp/file', shell=True)
    """
    def __init__(self, serial=''):
        self.serial = serial

    def _exec_cmd(self, args, shell, timeout, stderr):
        """Executes adb commands.

        Args:
            args: string or list of strings, program arguments.
                See subprocess.Popen() documentation.
            shell: bool, True to run this command through the system shell,
                False to invoke it directly. See subprocess.Popen() docs.
            timeout: float, the number of seconds to wait before timing out.
                If not specified, no timeout takes effect.
            stderr: a Byte stream, like io.BytesIO, stderr of the command will
                be written to this object if provided.

        Returns:
            The output of the adb command run if exit code is 0.

        Raises:
            ValueError: timeout value is invalid.
            AdbError: The adb command exit code is not 0.
            AdbTimeoutError: The adb command timed out.
        """
        if timeout and timeout <= 0:
            raise ValueError('Timeout is not a positive value: %s' % timeout)
        try:
            (ret, out, err) = utils.run_command(args,
                                                shell=shell,
                                                timeout=timeout)
        except psutil.TimeoutExpired:
            raise AdbTimeoutError(cmd=args,
                                  timeout=timeout,
                                  serial=self.serial)

        if stderr:
            stderr.write(err)
        logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
                      utils.cli_cmd_to_string(args), out, err, ret)
        if ret == 0:
            return out
        else:
            raise AdbError(cmd=args,
                           stdout=out,
                           stderr=err,
                           ret_code=ret,
                           serial=self.serial)

    def _execute_and_process_stdout(self, args, shell, handler):
        """Executes adb commands and processes the stdout with a handler.

        Args:
            args: string or list of strings, program arguments.
                See subprocess.Popen() documentation.
            shell: bool, True to run this command through the system shell,
                False to invoke it directly. See subprocess.Popen() docs.
            handler: func, a function to handle adb stdout line by line.

        Returns:
            The stderr of the adb command run if exit code is 0.

        Raises:
            AdbError: The adb command exit code is not 0.
        """
        proc = subprocess.Popen(args,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                shell=shell,
                                bufsize=1)
        out = '[elided, processed via handler]'
        try:
            # Even if the process dies, stdout.readline still works
            # and will continue until it runs out of stdout to process.
            while True:
                line = proc.stdout.readline()
                if line:
                    handler(line)
                else:
                    break
        finally:
            # Note, communicate will not contain any buffered output.
            (unexpected_out, err) = proc.communicate()
            if unexpected_out:
                out = '[unexpected stdout] %s' % unexpected_out
                for line in unexpected_out.splitlines():
                    handler(line)

        ret = proc.returncode
        logging.debug('cmd: %s, stdout: %s, stderr: %s, ret: %s',
                      utils.cli_cmd_to_string(args), out, err, ret)
        if ret == 0:
            return err
        else:
            raise AdbError(cmd=args, stdout=out, stderr=err, ret_code=ret)

    def _construct_adb_cmd(self, raw_name, args, shell):
        """Constructs an adb command with arguments for a subprocess call.

        Args:
            raw_name: string, the raw unsanitized name of the adb command to
                format.
            args: string or list of strings, arguments to the adb command.
                See subprocess.Proc() documentation.
            shell: bool, True to run this command through the system shell,
                False to invoke it directly. See subprocess.Proc() docs.

        Returns:
            The adb command in a format appropriate for subprocess. If shell is
                True, then this is a string; otherwise, this is a list of
                strings.
        """
        args = args or ''
        name = raw_name.replace('_', '-')
        if shell:
            args = utils.cli_cmd_to_string(args)
            # Add quotes around "adb" in case the ADB path contains spaces. This
            # is pretty common on Windows (e.g. Program Files).
            if self.serial:
                adb_cmd = '"%s" -s "%s" %s %s' % (ADB, self.serial, name, args)
            else:
                adb_cmd = '"%s" %s %s' % (ADB, name, args)
        else:
            adb_cmd = [ADB]
            if self.serial:
                adb_cmd.extend(['-s', self.serial])
            adb_cmd.append(name)
            if args:
                if isinstance(args, basestring):
                    adb_cmd.append(args)
                else:
                    adb_cmd.extend(args)
        return adb_cmd

    def _exec_adb_cmd(self, name, args, shell, timeout, stderr):
        adb_cmd = self._construct_adb_cmd(name, args, shell=shell)
        out = self._exec_cmd(adb_cmd,
                             shell=shell,
                             timeout=timeout,
                             stderr=stderr)
        return out

    def _execute_adb_and_process_stdout(self, name, args, shell, handler):
        adb_cmd = self._construct_adb_cmd(name, args, shell=shell)
        err = self._execute_and_process_stdout(adb_cmd,
                                               shell=shell,
                                               handler=handler)
        return err

    def _parse_getprop_output(self, output):
        """Parses the raw output of `adb shell getprop` into a dictionary.

        Args:
            output: byte str, the raw output of the `adb shell getprop` call.

        Returns:
            dict, name-value pairs of the properties.
        """
        output = output.decode('utf-8', errors='ignore').replace('\r\n', '\n')
        results = {}
        for line in output.split(']\n'):
            if not line:
                continue
            try:
                name, value = line.split(': ', 1)
            except ValueError:
                logging.debug('Failed to parse adb getprop line %s', line)
                continue
            name = name.strip()[1:-1]
            # Remove any square bracket from either end of the value string.
            if value and value[0] == '[':
                value = value[1:]
            results[name] = value
        return results

    def getprop(self, prop_name):
        """Get a property of the device.

        This is a convenience wrapper for `adb shell getprop xxx`.

        Args:
            prop_name: A string that is the name of the property to get.

        Returns:
            A string that is the value of the property, or None if the property
            doesn't exist.
        """
        return self.shell(
            ['getprop', prop_name],
            timeout=DEFAULT_GETPROP_TIMEOUT_SEC).decode('utf-8').strip()

    def getprops(self, prop_names):
        """Get multiple properties of the device.

        This is a convenience wrapper for `adb shell getprop`. Use this to
        reduce the number of adb calls when getting multiple properties.

        Args:
            prop_names: list of strings, the names of the properties to get.

        Returns:
            A dict containing name-value pairs of the properties requested, if
            they exist.
        """
        attempts = DEFAULT_GETPROPS_ATTEMPTS
        results = {}
        for attempt in range(attempts):
            # The ADB getprop command can randomly return empty string, so try
            # multiple times. This value should always be non-empty if the device
            # in a working state.
            raw_output = self.shell(['getprop'],
                                    timeout=DEFAULT_GETPROP_TIMEOUT_SEC)
            properties = self._parse_getprop_output(raw_output)
            if properties:
                for name in prop_names:
                    if name in properties:
                        results[name] = properties[name]
                break
            # Don't call sleep on the last attempt.
            if attempt < attempts - 1:
                time.sleep(DEFAULT_GETPROPS_RETRY_SLEEP_SEC)
        return results

    def has_shell_command(self, command):
        """Checks to see if a given check command exists on the device.

        Args:
            command: A string that is the name of the command to check.

        Returns:
            A boolean that is True if the command exists and False otherwise.
        """
        try:
            output = self.shell(['command', '-v',
                                 command]).decode('utf-8').strip()
            return command in output
        except AdbError:
            # If the command doesn't exist, then 'command -v' can return
            # an exit code > 1.
            return False

    def forward(self, args=None, shell=False):
        with ADB_PORT_LOCK:
            return self._exec_adb_cmd('forward',
                                      args,
                                      shell,
                                      timeout=None,
                                      stderr=None)

    def instrument(self, package, options=None, runner=None, handler=None):
        """Runs an instrumentation command on the device.

        This is a convenience wrapper to avoid parameter formatting.

        Example:

        .. code-block:: python

            device.instrument(
                'com.my.package.test',
                options = {
                    'class': 'com.my.package.test.TestSuite',
                },
            )

        Args:
            package: string, the package of the instrumentation tests.
            options: dict, the instrumentation options including the test
                class.
            runner: string, the test runner name, which defaults to
                DEFAULT_INSTRUMENTATION_RUNNER.
            handler: optional func, when specified the function is used to parse
                the instrumentation stdout line by line as the output is
                generated; otherwise, the stdout is simply returned once the
                instrumentation is finished.

        Returns:
            The stdout of instrumentation command or the stderr if the handler
                is set.
        """
        if runner is None:
            runner = DEFAULT_INSTRUMENTATION_RUNNER
        if options is None:
            options = {}

        options_list = []
        for option_key, option_value in options.items():
            options_list.append('-e %s %s' % (option_key, option_value))
        options_string = ' '.join(options_list)

        instrumentation_command = 'am instrument -r -w %s %s/%s' % (
            options_string, package, runner)
        logging.info('AndroidDevice|%s: Executing adb shell %s', self.serial,
                     instrumentation_command)
        if handler is None:
            return self._exec_adb_cmd('shell',
                                      instrumentation_command,
                                      shell=False,
                                      timeout=None,
                                      stderr=None)
        else:
            return self._execute_adb_and_process_stdout(
                'shell', instrumentation_command, shell=False, handler=handler)

    def __getattr__(self, name):
        def adb_call(args=None, shell=False, timeout=None, stderr=None):
            """Wrapper for an ADB command.

            Args:
                args: string or list of strings, arguments to the adb command.
                    See subprocess.Proc() documentation.
                shell: bool, True to run this command through the system shell,
                    False to invoke it directly. See subprocess.Proc() docs.
                timeout: float, the number of seconds to wait before timing out.
                    If not specified, no timeout takes effect.
                stderr: a Byte stream, like io.BytesIO, stderr of the command
                    will be written to this object if provided.

            Returns:
                The output of the adb command run if exit code is 0.
            """
            return self._exec_adb_cmd(name,
                                      args,
                                      shell=shell,
                                      timeout=timeout,
                                      stderr=stderr)

        return adb_call
