# -*- coding: utf-8 -*-
# Copyright 2010-2014, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Utility for Android.

Internally this depends on 'aapt' and 'jarsigner' commands so if they are not
on the path an exception will raise.

TODO(matsuzakit): Split to smaller modules (APK, AndroidDevice and Emulator).
"""

__author__ = "matsuzakit"

import fcntl
import glob
import logging
import os
import re
import subprocess
import sys
import zipfile


# Directory to store lock files.
LOCK_DIR = '/tmp/.android_util'


class Error(Exception):
  """Base exception class for all android_util errors."""


class AndroidUtilIOError(Error, IOError):
  """Domain specific IOError."""


class AndroidUtilSubprocessError(Error):
  """Subrocess which is invoked by this script throws error."""


class AndroidEmulatorConditionError(Error):
  """Emulator relating error."""


def GetApkProperties(apk_path):
  """Gets the properties of an apk.

  Args:
    apk_path: The path to the apk file as a string.

  Returns:
    Following properties will be in the returned dict.
    apk_file_name (string): Full path of the apk file.
    apk_size (int): File size of the apk file.
    classdex_{raw,compressed}_size (int):
        {Raw,Compressed} file size of classes.dex.
    has_release_key (boolean): True if the apk is signed with release key.
    libmozc_{raw,compressed}_size: {Raw,Compressed} file size of libmozc.so.
    native_code (list of string): Included native code's ABIs.
    res__file_count (int): Count of res/**/* files
    res_image_file__count (int): Count of res/**/*.{png,jpg,gif} files.
    res_image_{raw,compressed}_size_total (int):
        Total {raw,compressed} file size of res/**/*.{png,jpg,gif} files.
    res_{raw,compressed}_size_total (int):
        Total {raw,compressed} file size of res/**/* files.
    res_xml_file__count (int): Count of res/**/*.xml files.
    res_xml_{raw,compressed}_size_total (int):
        Total {raw,compressed} file size of res/**/*.xml files.
    uses_permissions (array of string): List of uses_permission.
    version_name (string): Version name.
    version_code (int): Version code.

  Raises:
    AndroidUtilIOError: If apk_file does not point to a file.
  """
  if not os.path.isfile(apk_path):
    raise AndroidUtilIOError('File not found: %s' % apk_path)
  apk_path = os.path.abspath(apk_path)

  props = {}
  props['apk_file_name'] = apk_path
  props['apk_size'] = os.path.getsize(apk_path)

  zip_file = zipfile.ZipFile(apk_path)
  try:
    _CollectMultipleFileMetrics(
        zip_file, r'lib/[^/]+/libmozc.so', 'libmozc', props)
    _CollectSingleFileMetrics(
        zip_file, r'classes.dex', 'classdex', props)
    _CollectMultipleFileMetrics(
        zip_file, r'res/.*', 'res', props)
    _CollectMultipleFileMetrics(
        zip_file, r'res/.*\.(png|jpg|gif)', 'res_image', props)
    _CollectMultipleFileMetrics(
        zip_file, r'res/.*\.xml', 'res_xml', props)
  finally:
    zip_file.close()

  _CollectBadgingProperties(apk_path, props)
  _CollectSignatureProperties(apk_path, props)

  return props


def _CollectBadgingProperties(apk_path, props):
  """Collects badging properties via aapt command.

  This method fills below properties;
  'native_code': Included native code's ABIs.
  'uses_permissions': Used permissions.
  'version_code': Version code of the apk file.
  'version_name': Version name of the apk file.

  Args:
    apk_path: Absolute path to apk file.
    props: A dictionary to be updated (property name to the value).
  """
  args = ['aapt', 'dump', 'badging', apk_path]
  logging.info('Collecting badging props; %s', args)
  (output, _) = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
  logging.debug(output)
  native_code_match = re.search(r'^native-code: (.*)$', output, re.MULTILINE)
  if native_code_match:
    native_code = native_code_match.group(1)
    props['native_code'] = native_code.replace('\'', '').split(' ')
  else:
    props['native_code'] = []
  props['uses_permissions'] = re.findall(r'^uses-permission:\'(.*)\'$',
                                         output, re.MULTILINE)
  props['version_code'] = int(re.search(r'versionCode=\'(\d+)\'',
                                        output).group(1))
  props['version_name'] = re.search(
      r'versionName=\'(\d+\.\d+\.\d+\.\d+(?:-\w+)?)\'', output).group(1)


def _CollectSignatureProperties(apk_path, props):
  """Collects signature relating properties via jarsigner command.

  This method fills below property;
  'has_release_key': True if the apk is signed with release key.

  Args:
    apk_path: Absolute path to apk file.
    props: A dictionary to be updated (property name to the value).
  """
  certificate = (r'X.509, CN=Unknown, OU="Google, Inc", O="Google, Inc", '
                 r'L=Mountain View, ST=CA, C=US')
  args = ['jarsigner', '-verify', '-verbose', '-certs', apk_path]
  logging.info('Collecting signature; %s', args)
  (output, _) = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
  logging.debug(output)
  props['has_release_key'] = output.find(certificate) != -1


def _CollectSingleFileMetrics(zip_file, name_pattern, key, props):
  """Collects metrics for given file.

  This method fills below properties;
  '%s_raw_size': Given file's raw (uncompressed) size.
  '%s_compressed_size': Given file's compressed size.

  Args:
    zip_file: A ZipFile in which target file exists.
    name_pattern: A regex pattern of the file names (str object).
      This pattern must match only one file.
    key: Key name of the retuned properties.
    props: A dictionary to be updated (property name to the value).

  Raises:
    AndroidUtilIOError: Given name_pattern matches nothing or multiple files.
  """
  info_list = _GetZipInfoList(zip_file, name_pattern)
  if len(info_list) != 1:
    raise AndroidUtilIOError('Given name_pattern (%s) must match '
                             'exactly one file but matched %d files.' %
                             (name_pattern, len(info_list)))
  info = info_list[0]
  props['%s_raw_size' % key] = info.file_size
  props['%s_compressed_size' % key] = info.compress_size


def _CollectMultipleFileMetrics(zip_file, name_pattern, key, props):
  """Collects metrics for given files.

  This method fills below propertes;
  '%s_file_count': Number of matched files.
  '%s_raw_size_total': Total raw size of matched files.
  '%s_compressed_size_total': Total compressed size of matched files.

  Args:
    zip_file: A ZipFile in which target file exists.
    name_pattern: A regex pattern of the file names (str object).
    key: Key name of the retuned properties.
    props: A dictionary (property name to the value).
  """
  info_list = _GetZipInfoList(zip_file, name_pattern)
  props['%s_file_count' % key] = len(info_list)
  props['%s_raw_size_total' % key] = sum(info.file_size for info in info_list)
  props['%s_compressed_size_total' % key] = sum(
      info.compress_size for info in info_list)


def _GetZipInfoList(zip_file, name_pattern):
  """Gets ZipInfo objects from zip_file.

  Args:
    zip_file: A ZipFile to be scaned.
    name_pattern: A regex pattern of the file names (str object).
  Returns:
    ZipInfo objects.
  """
  name_regex = re.compile(name_pattern)
  return [zip_info for zip_info in zip_file.infolist()
          if name_regex.match(zip_info.filename)]


class AndroidDevice(object):
  """Represents an Android device (an emulator or a real device).

  Attributes:
    serial: A string of serial. e.g. emulator-5554
            Serial can be seen by `adb devices` command.
    android_home: A string pointing the root directory of the SDK.
  """

  def __init__(self, serial, android_home):
    """Initializes with serial string.

    Args:
      serial: A serial string, which is set to self.serial.
      android_home: A string pointing the root directory of the SDK.
    """
    self.serial = serial
    # Don't access this property dicretly.
    # Use self._GetAvdName() instead.
    self._avd_name = None
    self._android_home = android_home

  def GetLogger(self):
    """Gets logger instance.

    Logger instance must not be a instance variable as
    AndroidDevice must be able to be pickled.

    Returns:
      Logger instance.
    """
    # If we have avd_name, create own logger and return it.
    # Don't keep this as an instance field.
    # AndroidDevice must be able to be pickled.
    if self._avd_name:
      logger = logging.getLogger(self._avd_name)
      logger.setLevel(logging.INFO)
      return logger
    # Otherwise return root logger.
    # Root logger is used at _GetAvdName()'s first call.
    return logging.getLogger()

  def WaitForDevice(self):
    """Equivalent to command "adb wait-for-device".

    Raises:
      AndroidUtilSubprocessError: wait-for-device is failed.
    """
    args = [os.path.join(self._android_home, 'platform-tools', 'adb'), '-s',
            self.serial, 'wait-for-device']
    if subprocess.call(args):
      raise AndroidUtilSubprocessError(
          'wait-for-device failed for %s' % self.serial)

  def IsAcceptableAbi(self, abi):
    """Returns if given abi is executable on this device.

    Args:
      abi: ABI name. e.g. armeabi, armeabi-v7a, x86, mips
    Returns:
      True if given abi is executable on this device.
    """
    return abi in (self.GetProperty(key) for key
                   in ['ro.product.cpu.abi', 'ro.product.cpu.abi2'])

  def _RunCommand(self, *command):
    """Run a command on android via adb.

    Args:
      *command: A list of arguments which are executed by Popen.
    Returns:
      stdout output of the invoked process.
    Raises:
      AndroidUtilSubprocessError: Failed to run given command.
    """
    args = [os.path.join(self._android_home, 'platform-tools', 'adb'),
            '-s', self.serial, 'shell']
    args.extend(command)
    self.GetLogger().info('Running at %s: %s', self.serial, args)
    process = subprocess.Popen(args, stdout=subprocess.PIPE)
    output, _ = process.communicate()
    if process.returncode != 0:
      raise AndroidUtilSubprocessError(
          'Failed to run the command: ' + ' '.join(command))
    for i in output.splitlines():
      self.GetLogger().info(i)
    return output

  def _GetAvdName(self):
    if not self._avd_name:
      # [mozc.avd_name] property is set by build_mozc.py
      self._avd_name = self.GetProperty('mozc.avd_name')
      # If the property is not available (e.g. on real device or an emulator
      # instance launched not from build_mozc.py),
      # use [ro.build.display.id].
      if not self._avd_name:
        self._avd_name = self.GetProperty('ro.build.display.id')
    return self._avd_name

  def GetProperty(self, key):
    return self._RunCommand('getprop', key).rstrip()

  @staticmethod
  def GetDevices(android_home):
    """Gets all the available devices via adb.

    The devices which are accessible from adb and of which status is
    'device' or 'offline' are returned.
    'unknown' devices are not included becuase it will never be accessible.

    Args:
      android_home: A string pointing the root directory of the SDK.

    Raises:
      AndroidUtilSubprocessError: when `adb` commands fails.
    Returns:
      A list of AndroidDevice.
    """
    args = [os.path.join(android_home, 'platform-tools', 'adb'), 'devices']
    logging.info('Running: %s', args)
    process = subprocess.Popen(args, stdout=subprocess.PIPE)
    output, _ = process.communicate()
    if process.returncode != 0:
      raise AndroidUtilSubprocessError(
          'Failed to run the command: ' + ' '.join(args))
    for i in output.splitlines():
      logging.info(i)
    result = []
    # offline is used for such emulator processes which have just been launched.
    regex = re.compile(r'(.*?)\s+(?:device|offline)$')
    for line in output.splitlines():
      match = regex.match(line)
      if match:
        result.append(AndroidDevice(match.group(1), android_home))
    return result


class Emulator(object):
  """An emulator and emulator related stuff."""

  @staticmethod
  def LaunchAll(android_sdk_home, avd_configs, android_home):
    """Creates and launches Emulator instances.

    Args:
      android_sdk_home: Path to android sdk home, containing .android directory.
      avd_configs: A list of dictionaries which contains parameters
                   for emulator.
      android_home: A string pointing the root directory of the SDK.

    Raises:
      AndroidEmulatorConditionError: No availabe ports.

    Returns:
      A list of Emulator instantces.
    """
    emulators = []

    ports = GetAvailableEmulatorPorts(android_home)
    if not ports:
      raise AndroidEmulatorConditionError('No ports for ADB are available')
    for avd_config in avd_configs:
      SetUpTestingSdkHomeDirectory(android_sdk_home,
                                   android_home,
                                   avd_config)
      avd_name = avd_config['--name']
      emulator = Emulator(android_sdk_home, avd_name, android_home)
      emulator.Launch()
      emulators.append(emulator)

    for emulator in emulators:
      emulator.GetAndroidDevice(android_home).WaitForDevice()
      logging.info('Emulator %s gets ready.', emulator.serial)

    return emulators

  def __init__(self, android_sdk_home, avd_name, android_home):
    """Create an Emulator instance.

    After instantiation, an emulator process is not lauched.
    To launch the process, call Launch method.
    Args:
      android_sdk_home: Path to android sdk home, containing .android directory.
      avd_name: Name of an avd to use.
      android_home: A string pointing the root directory of the SDK.
    """
    self._android_sdk_home = android_sdk_home
    self._avd_name = avd_name
    self._android_home = android_home
    self._avd_dir = os.path.join(android_sdk_home, '.android',
                                 'avd', '%s.avd' % avd_name)
    self._avd_properties = GetAvdProperties(android_sdk_home, avd_name)
    # _process can be used for checking whether emulator process has been
    # launched or not.
    self._process = None
    self._port_number = None
    self._lock_fd = None

  def _LockPort(self, port_number):
    """Trys to lock given port_number using lock file."""
    if not os.path.exists(LOCK_DIR):
      os.makedirs(LOCK_DIR)
    if self._port_number:
      raise AndroidUtilSubprocessError('Locked twice.')
    self._lock_fd = open(os.path.join(LOCK_DIR, 'port%d.lock' % port_number),
                         'w')
    try:
      fcntl.flock(self._lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
      logging.info('Port %d is alredy used.', port_number)
      self._lock_fd.close()
      return False
    return True

  def Launch(self):
    """Launhes an emulator process.

    Raises:
      AndroidUtilSubprocessError: If fails on launching a process.
    """
    if self._process:
      raise AndroidUtilSubprocessError(
          'Emulator process has been launched already.')

    ports = GetAvailableEmulatorPorts(self._android_home)
    for port in ports:
      if self._LockPort(port):
        self._port_number = port
        break
    if not self._port_number:
      raise AndroidUtilSubprocessError('No available port.')

    self.serial = 'emulator-%s' % self._port_number

    args = [
        os.path.join(self._android_home, 'tools', 'emulator'),
        '-avd', self._avd_name,
        '-port', str(self._port_number),
        '-no-snapshot-load',  # Should do full-boot.
        '-no-snapshot-save',
        '-no-window',  # For headless environment.
        '-prop', 'mozc.avd_name=%s' % self._avd_name,
        '-verbose',
    ]
    logging.info('Launching an emulator; %s', args)
    # ANDROID_SDK_HOME: Where .avd file are located.
    # ANDROID_SDK_ROOT: Where SDK is installed.
    env = {'ANDROID_SDK_HOME': self._android_sdk_home,
           'ANDROID_SDK_ROOT': self._android_home}
    self._process = subprocess.Popen(args, env=env)
    if self._process.poll() is not None:
      raise AndroidUtilSubprocessError('Emulator launch fails.')

  def CopyTreeToSdCard(self, host_src_dir, sd_dest_dir):
    """Copies tree from host to SD card.

    Args:
      host_src_dir: Source path (host).
      sd_dest_dir: Destination path (SD card).
    Raises:
      AndroidUtilSubprocessError: If fails on mtools command.
    """
    if self._process:
      raise AndroidUtilSubprocessError(
          'Emulator process for %s has been launched already '
          'so SD card modifaction fails.' % self.serial)
    sdcard_path = os.path.join(self._avd_dir, 'sdcard.img')
    args = ['mtools', '-c', 'mcopy', '-i', sdcard_path, '-s', host_src_dir,
            '::%s' % sd_dest_dir]
    logging.info('Copying into SD card: %s', args)
    # The size of an SD card which mksdcard creates is invalid for mtools.
    # Skip format check by MTOOLS_SKIP_CHECK variable.
    if subprocess.call(args, env={'MTOOLS_SKIP_CHECK': '1'}):
      raise AndroidUtilSubprocessError(
          'Copying %s into SD card fails' % host_src_dir)

  def GetAndroidDevice(self, android_home):
    return AndroidDevice(self.serial, android_home)

  def Terminate(self):
    """Terminate the process.

    Raises:
      AndroidUtilSubprocessError: Emulator process has not been launded.
    """
    if not self._process:
      raise AndroidUtilSubprocessError(
          'Emulator process has not been launched.')
    self._process.terminate()
    self._process = None
    fcntl.flock(self._lock_fd, fcntl.LOCK_UN)
    self._lock_fd.close()


def GetAvailableEmulatorPorts(android_home):
  """Returns a list of ports which are available for an emulator.

  Returned port can be passed to Launch method as port parameter.
  Args:
    android_home: A string pointing the root directory of the SDK.
  Returns:
    List of available ports.
  """
  args = [os.path.join(android_home, 'platform-tools', 'adb'), 'devices']
  process = subprocess.Popen(args, stdout=subprocess.PIPE)
  (devices_result, _) = process.communicate()
  used_ports = set(int(port) for port
                   in re.findall(r'emulator-(\d+)', devices_result))
  return [port for port in xrange(5554, 5586, 2) if port not in used_ports]


def SetUpTestingSdkHomeDirectory(dest_android_sdk_home,
                                 android_home,
                                 options,
                                 my_open=open):
  """Creates AVD in testing sdk home directory based on given options.

  Args:
    dest_android_sdk_home: testing sdk home
    android_home: SDK's home (e.g, /home/me/android-sdk-linux_x86)
    options: dictionary which is passed to `android create avd' command
    my_open: For testing purpose

  Raises:
    AndroidUtilSubprocessError: thrown when AVD creation fails.
  """
  # Make sure destination directory.
  avd_dir = os.path.join(dest_android_sdk_home, '.android', 'avd')
  if not os.path.exists(avd_dir):
    os.makedirs(avd_dir)

  args = [os.path.join(android_home, 'tools', 'android'),
          'create', 'avd',
          '--force',
          '--sdcard', '512M',]
  for key, value in options.iteritems():
    args.extend([key, value])
  env = {'ANDROID_SDK_HOME': os.path.abspath(dest_android_sdk_home)}
  logging.info('Creating AVD: %s', args)
  if subprocess.call(args, env=env):
    raise AndroidUtilSubprocessError('AVD creation fails.')

  # Suppress usage stats dialog.
  ddmscfg_path = os.path.join(dest_android_sdk_home, '.android', 'ddms.cfg')
  with my_open(ddmscfg_path, 'w') as f:
    f.write('pingOptIn=false\n')
    f.write('pingId=0\n')


def GetAvdNames(android_sdk_home):
  """Returns avd names which are available in android_sdk_home."""
  result = []
  ini_file_glob = os.path.join(android_sdk_home, '.android', 'avd', '*.ini')
  for ini_file_path in glob.glob(ini_file_glob):
    result.append(os.path.splitext(os.path.basename(ini_file_path))[0])
  return result


def GetAvdProperties(android_sdk_home, avd_name, my_open=open):
  """Returns a property, which is based on ${avd_name}/config.ini file."""
  # Argument 'open' is for testing.
  config_path = os.path.join(android_sdk_home, '.android', 'avd',
                             '%s.avd' % avd_name, 'config.ini')
  result = {}
  with my_open(config_path, 'r') as f:
    for line in f:
      m = re.match(r'^(.*?)=(.*)$', line)
      if m:
        result[m.group(1)] = m.group(2)
  return result


def main():
  for arg in sys.argv[1:]:
    for item in sorted(GetApkProperties(arg).items()):
      print '%s: %s' % item


if __name__ == '__main__':
  main()
