# Copyright 2018 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Wrapper around the Android device abstraction from src/build/android.
"""

import logging
import os
import sys
import re

BASE_DIR = os.path.normpath(
    os.path.join(os.path.dirname(__file__), '..', '..', '..'))
ANDROID_DIR = os.path.join(BASE_DIR, 'build', 'android')
DEVICE_DIR = '/data/local/tmp/v8/'


class TimeoutException(Exception):
  def __init__(self, timeout, output=None):
    self.timeout = timeout
    self.output = output


class CommandFailedException(Exception):
  def __init__(self, status, output):
    self.status = status
    self.output = output


class _Driver(object):
  """Helper class to execute shell commands on an Android device."""
  def __init__(self, device=None):
    assert os.path.exists(ANDROID_DIR)
    sys.path.insert(0, ANDROID_DIR)

    # We import the dependencies only on demand, so that this file can be
    # imported unconditionally.
    import devil_chromium
    from devil.android import device_errors  # pylint: disable=import-error
    from devil.android import device_utils  # pylint: disable=import-error
    from devil.android.perf import cache_control  # pylint: disable=import-error
    from devil.android.perf import perf_control  # pylint: disable=import-error
    global cache_control
    global device_errors
    global perf_control

    devil_chromium.Initialize()

    # Find specified device or a single attached device if none was specified.
    # In case none or multiple devices are attached, this raises an exception.
    self.device = device_utils.DeviceUtils.HealthyDevices(
        retries=5, enable_usb_resets=True, device_arg=device)[0]

    # This remembers what we have already pushed to the device.
    self.pushed = set()

  def tear_down(self):
    """Clean up files after running all tests."""
    self.device.RemovePath(DEVICE_DIR, force=True, recursive=True)

  def push_file(self, host_dir, file_name, target_rel='.',
                skip_if_missing=False):
    """Push a single file to the device (cached).

    Args:
      host_dir: Absolute parent directory of the file to push.
      file_name: Name of the file to push.
      target_rel: Parent directory of the target location on the device
          (relative to the device's base dir for testing).
      skip_if_missing: Keeps silent about missing files when set. Otherwise logs
          error.
    """
    # TODO(sergiyb): Implement this method using self.device.PushChangedFiles to
    # avoid accessing low-level self.device.adb.
    file_on_host = os.path.join(host_dir, file_name)

    # Only push files not yet pushed in one execution.
    if file_on_host in self.pushed:
      return

    file_on_device_tmp = os.path.join(DEVICE_DIR, '_tmp_', file_name)
    file_on_device = os.path.join(DEVICE_DIR, target_rel, file_name)
    folder_on_device = os.path.dirname(file_on_device)

    # Only attempt to push files that exist.
    if not os.path.exists(file_on_host):
      if not skip_if_missing:
        logging.critical('Missing file on host: %s' % file_on_host)
      return

    # Work-around for 'text file busy' errors. Push the files to a temporary
    # location and then copy them with a shell command.
    output = self.device.adb.Push(file_on_host, file_on_device_tmp)
    # Success looks like this: '3035 KB/s (12512056 bytes in 4.025s)'.
    # Errors look like this: 'failed to copy  ... '.
    if output and not re.search('^[0-9]', output.splitlines()[-1]):
      logging.critical('PUSH FAILED: ' + output)
    self.device.adb.Shell('mkdir -p %s' % folder_on_device)
    self.device.adb.Shell('cp %s %s' % (file_on_device_tmp, file_on_device))
    self.pushed.add(file_on_host)

  def push_executable(self, shell_dir, target_dir, binary):
    """Push files required to run a V8 executable.

    Args:
      shell_dir: Absolute parent directory of the executable on the host.
      target_dir: Parent directory of the executable on the device (relative to
          devices' base dir for testing).
      binary: Name of the binary to push.
    """
    self.push_file(shell_dir, binary, target_dir)

    # Push external startup data. Backwards compatible for revisions where
    # these files didn't exist. Or for bots that don't produce these files.
    self.push_file(
        shell_dir,
        'natives_blob.bin',
        target_dir,
        skip_if_missing=True,
    )
    self.push_file(
        shell_dir,
        'snapshot_blob.bin',
        target_dir,
        skip_if_missing=True,
    )
    self.push_file(
        shell_dir,
        'snapshot_blob_trusted.bin',
        target_dir,
        skip_if_missing=True,
    )
    self.push_file(
        shell_dir,
        'icudtl.dat',
        target_dir,
        skip_if_missing=True,
    )

  def run(self, target_dir, binary, args, rel_path, timeout, env=None,
          logcat_file=False):
    """Execute a command on the device's shell.

    Args:
      target_dir: Parent directory of the executable on the device (relative to
          devices' base dir for testing).
      binary: Name of the binary.
      args: List of arguments to pass to the binary.
      rel_path: Relative path on device to use as CWD.
      timeout: Timeout in seconds.
      env: The environment variables with which the command should be run.
      logcat_file: File into which to stream adb logcat log.
    """
    binary_on_device = os.path.join(DEVICE_DIR, target_dir, binary)
    cmd = [binary_on_device] + args
    def run_inner():
      try:
        output = self.device.RunShellCommand(
            cmd,
            cwd=os.path.join(DEVICE_DIR, rel_path),
            check_return=True,
            env=env,
            timeout=timeout,
            retries=0,
        )
        return '\n'.join(output)
      except device_errors.AdbCommandFailedError as e:
        raise CommandFailedException(e.status, e.output)
      except device_errors.CommandTimeoutError as e:
        raise TimeoutException(timeout, e.output)


    if logcat_file:
      with self.device.GetLogcatMonitor(output_file=logcat_file) as logmon:
        result = run_inner()
      logmon.Close()
      return result
    else:
      return run_inner()

  def drop_ram_caches(self):
    """Drop ran caches on device."""
    cache = cache_control.CacheControl(self.device)
    cache.DropRamCaches()

  def set_high_perf_mode(self):
    """Set device into high performance mode."""
    perf = perf_control.PerfControl(self.device)
    perf.SetHighPerfMode()

  def set_default_perf_mode(self):
    """Set device into default performance mode."""
    perf = perf_control.PerfControl(self.device)
    perf.SetDefaultPerfMode()


_ANDROID_DRIVER = None
def android_driver(device=None):
  """Singleton access method to the driver class."""
  global _ANDROID_DRIVER
  if not _ANDROID_DRIVER:
    _ANDROID_DRIVER = _Driver(device)
  return _ANDROID_DRIVER
