#!/usr/bin/env python
#
# Copyright 2018 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 a Fushsia executable by delegating to
build/fuchsia/(exe|test)_runner.py.
"""

import argparse
import os
import re
import sys


SCRIPT_TEMPLATE = """\
#!/usr/bin/env python
#
# This file was generated by build/fuchsia/create_runner_script.py

import os
import sys

def main():
  script_directory = os.path.dirname(__file__)

  def ResolvePath(path):
    \"\"\"Returns an absolute filepath given a path relative to this script.
    \"\"\"
    return os.path.abspath(os.path.join(script_directory, path))

  runner_path = ResolvePath('{runner_path}')
  runner_args = {runner_args}
  runner_path_args = {runner_path_args}
  for arg, path in runner_path_args:
    runner_args.extend([arg, ResolvePath(path)])

  os.execv(runner_path,
           [runner_path] + runner_args + sys.argv[1:])

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


def main(args):
  parser = argparse.ArgumentParser()
  parser.add_argument('--runner-script',
                      help='Name of the runner script to use.')
  parser.add_argument('--script-output-path',
                      help='Output path for executable script.')
  parser.add_argument('--test-runner-path',
                      help='Path to test_runner.py (optional).')
  group = parser.add_argument_group('Test runner path arguments.')
  group.add_argument('--output-directory')
  group.add_argument('--package')
  group.add_argument('--package-dep', action='append', default=[])
  group.add_argument('--package-manifest')
  args, runner_args = parser.parse_known_args(args)

  def RelativizePathToScript(path):
    """Returns the path relative to the output script directory."""
    return os.path.relpath(path, os.path.dirname(args.script_output_path))

  runner_path = args.test_runner_path or os.path.join(
      os.path.dirname(__file__), args.runner_script)
  runner_path = RelativizePathToScript(runner_path)

  runner_path_args = []
  runner_path_args.append(
      ('--output-directory', RelativizePathToScript(args.output_directory)))
  runner_path_args.append(
      ('--package', RelativizePathToScript(args.package)))
  for next_package_dep in args.package_dep:
    runner_path_args.append(
        ('--package-dep', RelativizePathToScript(next_package_dep)))
  runner_path_args.append(
      ('--package-manifest', RelativizePathToScript(args.package_manifest)))

  with open(args.script_output_path, 'w') as script:
    script.write(SCRIPT_TEMPLATE.format(
        runner_path=str(runner_path),
        runner_args=repr(runner_args),
        runner_path_args=repr(runner_path_args)))

  # Sets the mode of the generated script so that it is executable by the
  # current user.
  os.chmod(args.script_output_path, 0750)


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