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

"""The main module for the APK Crawler application."""

import getopt
import os
import subprocess
import sys
import time

from com.dtmilano.android.common import obtainAdbPath
from com.dtmilano.android.viewclient import ViewClient
import crawlpkg

ADB_PATH = obtainAdbPath()
HELP_MSG = ('Capsule usage:\n'
            'python capsule.py DEVICE_SERIAL [flag] <argument>\n'
            'No command line flags -- crawl current package\n'
            '-d or --dir /PATH_TO_APKS/  -- install and run APKS from a '
            'directory.\n'
            '-f or --file /[PATH TO FILE]/list.txt -- load text file of '
            'package names on device and crawl them.\n'
            '-r or --recrawl -- recrawl already explored apps.\n'
            '-h or --help -- help, list options')

# PyDev sets PYTHONPATH, use it
try:
  for p in os.environ['PYTHONPATH'].split(':'):
    if p not in sys.path:
      sys.path.append(p)
except KeyError:
  print 'Please set the environment variable PYTHONPATH'

try:
  sys.path.append(os.path.join(os.environ['ANDROID_VIEW_CLIENT_HOME'], 'src'))
except KeyError:
  print 'Please set the environment variable ANDROID_VIEW_CLIENT_HOME'


def load_pkgs_from_dir(dir_path):
  """Return all of the package names in a directory."""

  # Allow user to input either relative or absolute path to directory.
  directory = os.path.join(os.getcwd() + dir_path)
  if os.path.exists(directory):
    names = sorted(os.listdir(directory))
    pkg_list = [os.path.join(directory + n) for n in names if '.apk' in n]
  elif os.path.exists(dir_path):
    names = sorted(os.listdir(dir_path))
    pkg_list = [os.path.join(dir_path + n) for n in names if '.apk' in n]
  else:
    print 'Directory does not exist.'
    return []

  return pkg_list


def load_pkgs_from_file(filename):
  """Return all of the package names listed in a text file."""

  # Allow user to input either relative or absolute path.
  f = os.path.join(os.getcwd() + filename)
  if os.path.isfile(f):
    pkg_list = [pkg.strip('\n') for pkg in open(f)]
    return sorted(pkg_list)
  elif os.path.isfile(filename):
    pkg_list = [pkg.strip('\n') for pkg in open(filename)]
    return sorted(pkg_list)
  else:
    print 'File does not exist.'
    return []


if __name__ == '__main__':

  # Should we uninstall APKs once we install them. Setting it to true allows us
  # to do bulk crawling since we do not need to worry about the device memory
  # filling up.
  uninstall = False
  recrawl = False
  package_list = []

  try:
    kwargs1 = {'verbose': True, 'ignoresecuredevice': True, 'timeout': 20}
    kwargs2 = {'startviewserver': True, 'forceviewserveruse': True,
               'autodump': False, 'ignoreuiautomatorkilled': True}
    device, serialno = ViewClient.connectToDeviceOrExit(**kwargs1)
    vc = ViewClient(device, serialno, **kwargs2)
  except (RuntimeError, subprocess.CalledProcessError):
    print 'Error, device not found or not specified.'
    print HELP_MSG
    sys.exit()

  if any(a in sys.argv for a in ['-h', '--help']):
    print HELP_MSG
    sys.exit()

  # User only specified emulator name or nothing at all.
  if len(sys.argv) <= 2:
    print 'No command line arguments, crawling currently launched app.'
    crawlpkg.crawl_package(vc, device, serialno)
  # Command line argument is only valid if the user entered the filename,
  # emulator name, one option flag, and one argument.
  elif len(sys.argv) == 3:
    print 'Invalid argument structure.'
    print HELP_MSG
  elif len(sys.argv) >= 4:
    try:
      opts, _ = getopt.getopt(sys.argv[2:], 'd:f:h:r', ['directory=', 'file='])
    except getopt.GetoptError as err:
      print str(err)
      print HELP_MSG
      sys.exit()

    # This infrastructure allows us to add additional command line argument
    # possibilities easily.
    for opt, arg in opts:
      if opt in ('-d', '--dir'):
        uninstall = True
        package_list = load_pkgs_from_dir(arg)
      elif opt in ('-f', '--file'):
        package_list = load_pkgs_from_file(arg)
      elif opt in ('-h', '--help'):
        print HELP_MSG
      elif opt in ('-r', '--recrawl'):
        recrawl = True
      else:
        print ('Unhandled option. Use -h or --help for a listing of '
               'commands')
        sys.exit()

    if package_list:
      print 'Packages to be crawled: ' + ', '.join(package_list)

    for package in package_list:
      # Possibly install, then launch and crawl the app. device.shell() does
      # not support the install or launch.
      package_name = ''
      should_crawl = True
      if '.apk' in package:
        package_name = crawlpkg.extract_between(package, '/', '.apk', -1)
        subprocess.call([ADB_PATH, '-s', serialno, 'install', '-r', package])

      else:
        # We have the package name but not the .apk file.
        package_name = package.split('/')[-1]
        # Make sure the package is installed on the device by checking it
        # against installed third-party packages.
        installed_pkgs = device.shell('pm list packages -3')
        if package_name not in installed_pkgs:
          print 'Cannot find the package on the device: ' + package_name
          should_crawl = False

      if os.path.exists(os.path.dirname(os.path.abspath(__file__)) + '/data/' +
                        package_name) and not recrawl:
        should_crawl = False
        print 'Skipping ' + package_name + '; package has already been crawled.'

      if should_crawl:
        print 'Crawling ' + package_name

        # Launch the app.
        device.shell('monkey -p ' + package_name +
                     ' -c android.intent.category.LAUNCHER 1')
        time.sleep(5)

        crawlpkg.crawl_package(vc, device, serialno, package_name)

        if uninstall:
          print 'uninstall' + package_name
          subprocess.call([ADB_PATH, '-s', serialno, 'uninstall', package_name])

  else:
    print 'Invalid number of command line arguments.'
    print HELP_MSG
