#!/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-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)))
  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:]))
