#!/usr/bin/env python

# Copyright 2015 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.

"""Creates a script to run an "_incremental" .apk."""

import argparse
import os
import pprint
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, 'gyp'))

from pylib.constants import host_paths
from util import build_utils


SCRIPT_TEMPLATE = """\
#!/usr/bin/env python
#
# This file was generated by:
#     //build/android/incremental_install/create_install_script.py

import os
import subprocess
import sys


def _ResolvePath(path):
  script_directory = os.path.dirname(__file__)
  return os.path.abspath(os.path.join(script_directory, path))


# Exported to allow test runner to be able to install incremental apks.
def GetInstallParameters():
  apk_path = {apk_path}
  dex_files = {dex_files}
  dont_even_try = {dont_even_try}
  native_libs = {native_libs}
  show_proguard_warning = {show_proguard_warning}
  splits = {splits}

  return dict(apk_path=_ResolvePath(apk_path),
              dex_files=[_ResolvePath(p) for p in dex_files],
              dont_even_try=dont_even_try,
              native_libs=[_ResolvePath(p) for p in native_libs],
              show_proguard_warning=show_proguard_warning,
              splits=[_ResolvePath(p) for p in splits])


def main():
  output_directory = {output_directory}
  cmd_path = {cmd_path}
  params = GetInstallParameters()
  cmd_args = [
      _ResolvePath(cmd_path),
      '--output-directory', _ResolvePath(output_directory),
  ]
  for native_lib in params['native_libs']:
    cmd_args.extend(('--native_lib', native_lib))
  for dex_path in params['dex_files']:
    cmd_args.extend(('--dex-file', dex_path))
  for split in params['splits']:
    cmd_args.extend(('--split', split))
  cmd_args.append(params['apk_path'])
  if params['dont_even_try']:
    cmd_args.extend(('--dont-even-try', params['dont_even_try']))
  if params['show_proguard_warning']:
    cmd_args.append('--show-proguard-warning')
  return subprocess.call(cmd_args + sys.argv[1:])

if __name__ == '__main__':
  sys.exit(main())
"""


def _ParseArgs(args):
  args = build_utils.ExpandFileArgs(args)
  parser = argparse.ArgumentParser()
  build_utils.AddDepfileOption(parser)
  parser.add_argument('--script-output-path',
                      help='Output path for executable script.',
                      required=True)
  parser.add_argument('--output-directory',
                      help='Path to the root build directory.',
                      default='.')
  parser.add_argument('--apk-path',
                      help='Path to the .apk to install.',
                      required=True)
  parser.add_argument('--split',
                      action='append',
                      dest='splits',
                      default=[],
                      help='A glob matching the apk splits. '
                           'Can be specified multiple times.')
  parser.add_argument('--native-libs',
                      action='append',
                      default=[],
                      help='GYP-list of paths to native libraries. Can be '
                      'repeated.')
  parser.add_argument('--dex-file',
                      action='append',
                      default=[],
                      dest='dex_files',
                      help='List of dex files to include.')
  parser.add_argument('--dex-file-list',
                      help='GYP-list of dex files.')
  parser.add_argument('--show-proguard-warning',
                      action='store_true',
                      default=False,
                      help='Print a warning about proguard being disabled')
  parser.add_argument('--dont-even-try',
                      help='Prints this message and exits.')

  options = parser.parse_args(args)
  options.dex_files += build_utils.ParseGypList(options.dex_file_list)
  all_libs = []
  for gyp_list in options.native_libs:
    all_libs.extend(build_utils.ParseGypList(gyp_list))
  options.native_libs = all_libs
  return options


def main(args):
  options = _ParseArgs(args)

  def relativize(path):
    script_dir = os.path.dirname(options.script_output_path)
    return path and os.path.relpath(path, script_dir)

  installer_path = os.path.join(host_paths.DIR_SOURCE_ROOT, 'build', 'android',
                                'incremental_install', 'installer.py')
  pformat = pprint.pformat
  template_args = {
      'cmd_path': pformat(relativize(installer_path)),
      'apk_path': pformat(relativize(options.apk_path)),
      'output_directory': pformat(relativize(options.output_directory)),
      'native_libs': pformat([relativize(p) for p in options.native_libs]),
      'dex_files': pformat([relativize(p) for p in options.dex_files]),
      'dont_even_try': pformat(options.dont_even_try),
      'show_proguard_warning': pformat(options.show_proguard_warning),
      'splits': pformat([relativize(p) for p in options.splits]),
  }

  with open(options.script_output_path, 'w') as script:
    script.write(SCRIPT_TEMPLATE.format(**template_args))

  os.chmod(options.script_output_path, 0750)

  if options.depfile:
    build_utils.WriteDepfile(
        options.depfile,
        build_utils.GetPythonDependencies())


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
