# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Provides an interface to start and stop Android emulator.

  Emulator: The class provides the methods to launch/shutdown the emulator with
            the android virtual device named 'avd_armeabi' .
"""

import logging
import os
import signal
import subprocess
import time

# TODO(craigdh): Move these pylib dependencies to pylib/utils/.
from pylib import android_commands
from pylib import cmd_helper
from pylib import constants
from pylib import pexpect
from pylib.device import device_utils
from pylib.utils import time_profile

import errors
import run_command

# SD card size
SDCARD_SIZE = '512M'

# Template used to generate config.ini files for the emulator
CONFIG_TEMPLATE = """avd.ini.encoding=ISO-8859-1
hw.dPad=no
hw.lcd.density=320
sdcard.size=512M
hw.cpu.arch={hw.cpu.arch}
hw.device.hash=-708107041
hw.camera.back=none
disk.dataPartition.size=800M
hw.gpu.enabled=yes
skin.path=720x1280
skin.dynamic=yes
hw.keyboard=yes
hw.ramSize=1024
hw.device.manufacturer=Google
hw.sdCard=yes
hw.mainKeys=no
hw.accelerometer=yes
skin.name=720x1280
abi.type={abi.type}
hw.trackBall=no
hw.device.name=Galaxy Nexus
hw.battery=yes
hw.sensors.proximity=yes
image.sysdir.1=system-images/android-{api.level}/{abi.type}/
hw.sensors.orientation=yes
hw.audioInput=yes
hw.camera.front=none
hw.gps=yes
vm.heapSize=128
{extras}"""

CONFIG_REPLACEMENTS = {
  'x86': {
    '{hw.cpu.arch}': 'x86',
    '{abi.type}': 'x86',
    '{extras}': ''
  },
  'arm': {
    '{hw.cpu.arch}': 'arm',
    '{abi.type}': 'armeabi-v7a',
    '{extras}': 'hw.cpu.model=cortex-a8\n'
  },
  'mips': {
    '{hw.cpu.arch}': 'mips',
    '{abi.type}': 'mips',
    '{extras}': ''
  }
}

class EmulatorLaunchException(Exception):
  """Emulator failed to launch."""
  pass

def _KillAllEmulators():
  """Kill all running emulators that look like ones we started.

  There are odd 'sticky' cases where there can be no emulator process
  running but a device slot is taken.  A little bot trouble and and
  we're out of room forever.
  """
  emulators = android_commands.GetAttachedDevices(hardware=False)
  if not emulators:
    return
  for emu_name in emulators:
    cmd_helper.RunCmd(['adb', '-s', emu_name, 'emu', 'kill'])
  logging.info('Emulator killing is async; give a few seconds for all to die.')
  for _ in range(5):
    if not android_commands.GetAttachedDevices(hardware=False):
      return
    time.sleep(1)


def DeleteAllTempAVDs():
  """Delete all temporary AVDs which are created for tests.

  If the test exits abnormally and some temporary AVDs created when testing may
  be left in the system. Clean these AVDs.
  """
  avds = device_utils.GetAVDs()
  if not avds:
    return
  for avd_name in avds:
    if 'run_tests_avd' in avd_name:
      cmd = ['android', '-s', 'delete', 'avd', '--name', avd_name]
      cmd_helper.RunCmd(cmd)
      logging.info('Delete AVD %s' % avd_name)


class PortPool(object):
  """Pool for emulator port starting position that changes over time."""
  _port_min = 5554
  _port_max = 5585
  _port_current_index = 0

  @classmethod
  def port_range(cls):
    """Return a range of valid ports for emulator use.

    The port must be an even number between 5554 and 5584.  Sometimes
    a killed emulator "hangs on" to a port long enough to prevent
    relaunch.  This is especially true on slow machines (like a bot).
    Cycling through a port start position helps make us resilient."""
    ports = range(cls._port_min, cls._port_max, 2)
    n = cls._port_current_index
    cls._port_current_index = (n + 1) % len(ports)
    return ports[n:] + ports[:n]


def _GetAvailablePort():
  """Returns an available TCP port for the console."""
  used_ports = []
  emulators = android_commands.GetAttachedDevices(hardware=False)
  for emulator in emulators:
    used_ports.append(emulator.split('-')[1])
  for port in PortPool.port_range():
    if str(port) not in used_ports:
      return port


def LaunchTempEmulators(emulator_count, abi, api_level, wait_for_boot=True):
  """Create and launch temporary emulators and wait for them to boot.

  Args:
    emulator_count: number of emulators to launch.
    abi: the emulator target platform
    api_level: the api level (e.g., 19 for Android v4.4 - KitKat release)
    wait_for_boot: whether or not to wait for emulators to boot up

  Returns:
    List of emulators.
  """
  emulators = []
  for n in xrange(emulator_count):
    t = time_profile.TimeProfile('Emulator launch %d' % n)
    # Creates a temporary AVD.
    avd_name = 'run_tests_avd_%d' % n
    logging.info('Emulator launch %d with avd_name=%s and api=%d',
        n, avd_name, api_level)
    emulator = Emulator(avd_name, abi)
    emulator.CreateAVD(api_level)
    emulator.Launch(kill_all_emulators=n == 0)
    t.Stop()
    emulators.append(emulator)
  # Wait for all emulators to boot completed.
  if wait_for_boot:
    for emulator in emulators:
      emulator.ConfirmLaunch(True)
  return emulators


def LaunchEmulator(avd_name, abi):
  """Launch an existing emulator with name avd_name.

  Args:
    avd_name: name of existing emulator
    abi: the emulator target platform

  Returns:
    emulator object.
  """
  logging.info('Specified emulator named avd_name=%s launched', avd_name)
  emulator = Emulator(avd_name, abi)
  emulator.Launch(kill_all_emulators=True)
  emulator.ConfirmLaunch(True)
  return emulator


class Emulator(object):
  """Provides the methods to launch/shutdown the emulator.

  The emulator has the android virtual device named 'avd_armeabi'.

  The emulator could use any even TCP port between 5554 and 5584 for the
  console communication, and this port will be part of the device name like
  'emulator-5554'. Assume it is always True, as the device name is the id of
  emulator managed in this class.

  Attributes:
    emulator: Path of Android's emulator tool.
    popen: Popen object of the running emulator process.
    device: Device name of this emulator.
  """

  # Signals we listen for to kill the emulator on
  _SIGNALS = (signal.SIGINT, signal.SIGHUP)

  # Time to wait for an emulator launch, in seconds.  This includes
  # the time to launch the emulator and a wait-for-device command.
  _LAUNCH_TIMEOUT = 120

  # Timeout interval of wait-for-device command before bouncing to a a
  # process life check.
  _WAITFORDEVICE_TIMEOUT = 5

  # Time to wait for a "wait for boot complete" (property set on device).
  _WAITFORBOOT_TIMEOUT = 300

  def __init__(self, avd_name, abi):
    """Init an Emulator.

    Args:
      avd_name: name of the AVD to create
      abi: target platform for emulator being created, defaults to x86
    """
    android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk')
    self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator')
    self.android = os.path.join(android_sdk_root, 'tools', 'android')
    self.popen = None
    self.device_serial = None
    self.abi = abi
    self.avd_name = avd_name

  @staticmethod
  def _DeviceName():
    """Return our device name."""
    port = _GetAvailablePort()
    return ('emulator-%d' % port, port)

  def CreateAVD(self, api_level):
    """Creates an AVD with the given name.

    Args:
      api_level: the api level of the image

    Return avd_name.
    """

    if self.abi == 'arm':
      abi_option = 'armeabi-v7a'
    elif self.abi == 'mips':
      abi_option = 'mips'
    else:
      abi_option = 'x86'

    api_target = 'android-%s' % api_level

    avd_command = [
        self.android,
        '--silent',
        'create', 'avd',
        '--name', self.avd_name,
        '--abi', abi_option,
        '--target', api_target,
        '--sdcard', SDCARD_SIZE,
        '--force',
    ]
    avd_cmd_str = ' '.join(avd_command)
    logging.info('Create AVD command: %s', avd_cmd_str)
    avd_process = pexpect.spawn(avd_cmd_str)

    # Instead of creating a custom profile, we overwrite config files.
    avd_process.expect('Do you wish to create a custom hardware profile')
    avd_process.sendline('no\n')
    avd_process.expect('Created AVD \'%s\'' % self.avd_name)

    # Replace current configuration with default Galaxy Nexus config.
    avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd')
    ini_file = os.path.join(avds_dir, '%s.ini' % self.avd_name)
    new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name,
                                  'config.ini')

    # Remove config files with defaults to replace with Google's GN settings.
    os.unlink(ini_file)
    os.unlink(new_config_ini)

    # Create new configuration files with Galaxy Nexus by Google settings.
    with open(ini_file, 'w') as new_ini:
      new_ini.write('avd.ini.encoding=ISO-8859-1\n')
      new_ini.write('target=%s\n' % api_target)
      new_ini.write('path=%s/%s.avd\n' % (avds_dir, self.avd_name))
      new_ini.write('path.rel=avd/%s.avd\n' % self.avd_name)

    custom_config = CONFIG_TEMPLATE
    replacements = CONFIG_REPLACEMENTS[self.abi]
    for key in replacements:
      custom_config = custom_config.replace(key, replacements[key])
    custom_config = custom_config.replace('{api.level}', str(api_level))

    with open(new_config_ini, 'w') as new_config_ini:
      new_config_ini.write(custom_config)

    return self.avd_name


  def _DeleteAVD(self):
    """Delete the AVD of this emulator."""
    avd_command = [
        self.android,
        '--silent',
        'delete',
        'avd',
        '--name', self.avd_name,
    ]
    logging.info('Delete AVD command: %s', ' '.join(avd_command))
    cmd_helper.RunCmd(avd_command)


  def Launch(self, kill_all_emulators):
    """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the
    emulator is ready for use.

    If fails, an exception will be raised.
    """
    if kill_all_emulators:
      _KillAllEmulators()  # just to be sure
    self._AggressiveImageCleanup()
    (self.device_serial, port) = self._DeviceName()
    emulator_command = [
        self.emulator,
        # Speed up emulator launch by 40%.  Really.
        '-no-boot-anim',
        # The default /data size is 64M.
        # That's not enough for 8 unit test bundles and their data.
        '-partition-size', '512',
        # Use a familiar name and port.
        '-avd', self.avd_name,
        '-port', str(port),
        # Wipe the data.  We've seen cases where an emulator gets 'stuck' if we
        # don't do this (every thousand runs or so).
        '-wipe-data',
        # Enable GPU by default.
        '-gpu', 'on',
        '-qemu', '-m', '1024',
        ]
    if self.abi == 'x86':
      emulator_command.extend([
          # For x86 emulator --enable-kvm will fail early, avoiding accidental
          # runs in a slow mode (i.e. without hardware virtualization support).
          '--enable-kvm',
          ])

    logging.info('Emulator launch command: %s', ' '.join(emulator_command))
    self.popen = subprocess.Popen(args=emulator_command,
                                  stderr=subprocess.STDOUT)
    self._InstallKillHandler()

  @staticmethod
  def _AggressiveImageCleanup():
    """Aggressive cleanup of emulator images.

    Experimentally it looks like our current emulator use on the bot
    leaves image files around in /tmp/android-$USER.  If a "random"
    name gets reused, we choke with a 'File exists' error.
    TODO(jrg): is there a less hacky way to accomplish the same goal?
    """
    logging.info('Aggressive Image Cleanup')
    emulator_imagedir = '/tmp/android-%s' % os.environ['USER']
    if not os.path.exists(emulator_imagedir):
      return
    for image in os.listdir(emulator_imagedir):
      full_name = os.path.join(emulator_imagedir, image)
      if 'emulator' in full_name:
        logging.info('Deleting emulator image %s', full_name)
        os.unlink(full_name)

  def ConfirmLaunch(self, wait_for_boot=False):
    """Confirm the emulator launched properly.

    Loop on a wait-for-device with a very small timeout.  On each
    timeout, check the emulator process is still alive.
    After confirming a wait-for-device can be successful, make sure
    it returns the right answer.
    """
    seconds_waited = 0
    number_of_waits = 2  # Make sure we can wfd twice
    # TODO(jbudorick) Un-handroll this in the implementation switch.
    adb_cmd = "adb -s %s %s" % (self.device_serial, 'wait-for-device')
    while seconds_waited < self._LAUNCH_TIMEOUT:
      try:
        run_command.RunCommand(adb_cmd,
                               timeout_time=self._WAITFORDEVICE_TIMEOUT,
                               retry_count=1)
        number_of_waits -= 1
        if not number_of_waits:
          break
      except errors.WaitForResponseTimedOutError:
        seconds_waited += self._WAITFORDEVICE_TIMEOUT
        adb_cmd = "adb -s %s %s" % (self.device_serial, 'kill-server')
        run_command.RunCommand(adb_cmd)
      self.popen.poll()
      if self.popen.returncode != None:
        raise EmulatorLaunchException('EMULATOR DIED')
    if seconds_waited >= self._LAUNCH_TIMEOUT:
      raise EmulatorLaunchException('TIMEOUT with wait-for-device')
    logging.info('Seconds waited on wait-for-device: %d', seconds_waited)
    if wait_for_boot:
      # Now that we checked for obvious problems, wait for a boot complete.
      # Waiting for the package manager is sometimes problematic.
      # TODO(jbudorick) Convert this once waiting for the package manager and
      #                 the external storage is no longer problematic.
      d = device_utils.DeviceUtils(self.device_serial)
      d.old_interface.WaitForSystemBootCompleted(self._WAITFORBOOT_TIMEOUT)

  def Shutdown(self):
    """Shuts down the process started by launch."""
    self._DeleteAVD()
    if self.popen:
      self.popen.poll()
      if self.popen.returncode == None:
        self.popen.kill()
      self.popen = None

  def _ShutdownOnSignal(self, _signum, _frame):
    logging.critical('emulator _ShutdownOnSignal')
    for sig in self._SIGNALS:
      signal.signal(sig, signal.SIG_DFL)
    self.Shutdown()
    raise KeyboardInterrupt  # print a stack

  def _InstallKillHandler(self):
    """Install a handler to kill the emulator when we exit unexpectedly."""
    for sig in self._SIGNALS:
      signal.signal(sig, self._ShutdownOnSignal)
